回答

收藏

如何在Dapper中使用“在哪里”

技术问答 技术问答 492 人阅读 | 0 人回复 | 2023-09-14

我一直在尝试失败,在Dapper中使用IEnumerablewith withWHERE IN子句已经有一段时间了。
! f9 A$ J$ @: A3 S8 Q* f在文档中,它确实说IEnumerable<i>支持在a中使用,WHERE IN但我什至无法使它正常工作。
& ~  z3 g5 `! }& X  ^, p. zDapper allow you to pass in IEnumerable<i> and will automatically
0 l3 D3 l& ]8 N8 X& B  Uparameterize your query.
0 k' d) [( Z: \/ a我不断收到的错误消息是Sql语法错误。 Incorrect syntax near ','.5 G' l2 Z- f" U9 U! K. L; o
我整理了一些测试代码,希望它们能证明我正在尝试实现的目标。( V. l% R$ J3 J7 G5 L2 [

) |0 A% z; U# R8 m/ tstring connString = &quot;Server=*.*.*.*;Database=*;User Id=*assword=*;&quot;;
0 Z$ w+ T" I: N' x! G0 V4 M/ Ustring sqlStringIn = @&quot;SELECT StringText FROM ; o! h2 m9 k, {7 {
                (SELECT 1 ID, 'A' StringID, 'This is a test' StringText
/ |) r! H  r. d( Q0 m# c                UNION SELECT 2 ID, 'B' StringID, 'Another test' StringText' f4 U' x% ^, [
                UNION SELECT 3 ID, 'C' StringID, 'And another' StringText
$ y0 t: z8 d+ H% F6 S                UNION SELECT 4 ID, 'D' StringID, 'and again' StringText
0 ^/ b- O1 U' }8 T4 O. i* V( @) f                UNION SELECT 5 ID, 'E' StringID, 'yet again' StringText) data; X' q( I9 f3 \% o
                WHERE StringId IN (@str)&quot;;
: T6 ?5 j* E/ Dstring sqlIntegerIn = @&quot;SELECT StringText FROM
& P4 P. J1 U; r4 |* X+ z" e) [                (SELECT 1 ID, 'A' StringID, 'This is a test' StringText) c) E: V! c4 d/ P* R- o
                UNION SELECT 2 ID, 'B' StringID, 'Another test' StringText0 m& ^  N* J0 K+ j) F" y& d
                UNION SELECT 3 ID, 'C' StringID, 'And another' StringText% ~- H+ E" R* f; X) N5 D+ u
                UNION SELECT 4 ID, 'D' StringID, 'and again' StringText" r3 ?! _. B5 D) Z
                UNION SELECT 5 ID, 'E' StringID, 'yet again' StringText) data
( W- r7 h+ z) V% M                WHERE ID IN (@integer)&quot;;
' J: {+ G  q% W/ ^$ T" o. I1 N( N: U8 b' G
using (SqlConnection conn = new SqlConnection(connString))
" c# s6 }2 r0 g, ~{
/ v* F# d8 {/ O( G" _    conn.Open();) P! G& h( X3 K+ P% ?$ E- K
    List<i> integers = new List<i>{ 1, 2, 3 };
9 K3 G- p* V& I2 W( }    List strings = new List { &quot;A&quot;, &quot;B&quot;, &quot;C&quot; };
* r: W  x8 K: J6 J0 Z: x    var parameters = new {str = strings, integer = integers };
8 m- u- p) G3 M' C    //fails here9 S' J) h, R! ^; G9 u" f# J( \
    IEnumerable intTest = conn.Query(sqlIntegerIn, parameters, commandType: System.Data.CommandType.Text);
/ o, z5 u: s3 |. A    //and here+ \, [" Y- Y& x! ~
    IEnumerable stringTest = conn.Query(sqlStringIn, parameters, commandType: System.Data.CommandType.Text);
6 T" h- ?  Q, W4 F  q}; B* @5 a% @2 d
                7 `2 H) O# O8 i* b% F. X
解决方案:: Y3 V! o7 f% Z' [
                & L$ g( |! r4 l' ~

  ?. U4 G' H  N7 u9 z1 j& @8 V9 C$ P  h" T
                为了执行此处需要的操作,dapper需要即时更改SQL-因此需要 真正 确保它在做正确的事情。常规有效的SQL语法包括括号:
0 [: \: U. l7 R! s. ?4 [, u- |WHERE StringId IN (@str)
8 s  b# K0 T# g3 S% G6 }+ H  ]% k: B为了消除歧义, voodoo dapper语法 省略 了括号:4 h* S, N+ p  L+ R
WHERE StringId IN @str
! N2 l% |  _! x6 v+ @& e如果检测到此错误,它将查找名为的参数str,并将其扩展为以下参数之一:& T+ [# M) }0 Q. n8 Y; Z4 R
WHERE 1=0 -- if no values, V) W' M9 f- U5 s% }- T& X2 a
WHERE StringId = @str -- if exactly one value8 l' q/ V, c- `+ Y' t
WHERE StringId IN (@str0, @str1, ...) -- if more than one value
1 f' b: e4 i- }2 `# ^但简短的版本:删除括号。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则