回答

收藏

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

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

我一直在尝试失败,在Dapper中使用IEnumerablewith withWHERE IN子句已经有一段时间了。
! J( F& `: B& |8 a" v$ i7 ^/ M在文档中,它确实说IEnumerable<i>支持在a中使用,WHERE IN但我什至无法使它正常工作。
9 B% S1 V/ y' b; n4 j) QDapper allow you to pass in IEnumerable<i> and will automatically
. f+ j  F# y- H& [7 x! \# iparameterize your query.
# I; B: X) N/ i& s+ O4 Q我不断收到的错误消息是Sql语法错误。 Incorrect syntax near ','.
6 G4 n& E6 y& G+ f( B! L我整理了一些测试代码,希望它们能证明我正在尝试实现的目标。3 d3 b; I" y; P6 r

: S2 B+ [; t8 I: `string connString = &quot;Server=*.*.*.*;Database=*;User Id=*assword=*;&quot;;. V8 \, ^% Q; n2 u/ Y* E
string sqlStringIn = @&quot;SELECT StringText FROM : r6 x# t/ y) p0 v' K0 `9 @$ {6 S% m) z
                (SELECT 1 ID, 'A' StringID, 'This is a test' StringText$ V$ t) d# k  m: S; Z2 Y6 F: ^  [
                UNION SELECT 2 ID, 'B' StringID, 'Another test' StringText( z" R4 g4 P$ r; J& H& a3 q- c& K% d9 l
                UNION SELECT 3 ID, 'C' StringID, 'And another' StringText! ?1 ~! }* ~) f# W# ^; K4 m
                UNION SELECT 4 ID, 'D' StringID, 'and again' StringText
$ M3 b! c: Y; p7 O: m  o                UNION SELECT 5 ID, 'E' StringID, 'yet again' StringText) data* Z6 f+ W6 @9 p7 p" U- _* l/ i
                WHERE StringId IN (@str)&quot;;
3 s. |* D8 ]* Ystring sqlIntegerIn = @&quot;SELECT StringText FROM & R% E3 A9 A$ J6 E$ O
                (SELECT 1 ID, 'A' StringID, 'This is a test' StringText" T% v4 k/ O0 D& N5 e9 ]  t
                UNION SELECT 2 ID, 'B' StringID, 'Another test' StringText- U) c4 D7 j  k, M
                UNION SELECT 3 ID, 'C' StringID, 'And another' StringText  U/ s4 C7 c9 f! \
                UNION SELECT 4 ID, 'D' StringID, 'and again' StringText
9 k% i" O( a5 _9 f1 P8 D+ {                UNION SELECT 5 ID, 'E' StringID, 'yet again' StringText) data) T7 Q+ e, @1 ?3 q7 C
                WHERE ID IN (@integer)&quot;;
& O4 s9 |* j4 i" B& L( H9 y# m. Z9 h$ ^# w% ~
using (SqlConnection conn = new SqlConnection(connString))
1 {0 a" R8 t! }7 {, b, E! u{1 b5 Y3 b6 J5 p+ Q5 [3 q" E
    conn.Open();# v! m/ F2 T5 y9 y- B. i$ ^1 {
    List<i> integers = new List<i>{ 1, 2, 3 };
) n' U5 F$ [8 _  ]: v0 h    List strings = new List { &quot;A&quot;, &quot;B&quot;, &quot;C&quot; };
  X2 j2 D9 ?7 O8 T5 \* l0 X1 x  M; X    var parameters = new {str = strings, integer = integers };6 g- k7 f9 w* B$ q+ v
    //fails here
) m* o  Z% A! U; t' S    IEnumerable intTest = conn.Query(sqlIntegerIn, parameters, commandType: System.Data.CommandType.Text);3 J4 O$ \) G5 q7 _/ p  s% b
    //and here
+ e1 Q1 Y) s0 H    IEnumerable stringTest = conn.Query(sqlStringIn, parameters, commandType: System.Data.CommandType.Text);1 R  e% c" o& H
}
/ l! v# _6 e5 h9 _/ ]% `' i                & \* y  L) G. \2 T. \, J
解决方案:
. j+ H9 C3 a" g               
( u4 U0 u% a4 D+ h" w4 g% I, F
& }# R. D9 y- {- c$ X
7 z! F  T$ l* u                为了执行此处需要的操作,dapper需要即时更改SQL-因此需要 真正 确保它在做正确的事情。常规有效的SQL语法包括括号:- q- v  z6 o. p4 W  V
WHERE StringId IN (@str)
$ x" L$ K2 w+ y3 }为了消除歧义, voodoo dapper语法 省略 了括号:
( S  m; I- _4 c# `9 n, o* D: ~WHERE StringId IN @str
0 }0 k; Z" d5 o  B; X0 \如果检测到此错误,它将查找名为的参数str,并将其扩展为以下参数之一:
* e* g+ ^9 l. t+ Y4 h- XWHERE 1=0 -- if no values) W% X! {  K, y. @) D
WHERE StringId = @str -- if exactly one value* e4 ]: O; d7 u& v
WHERE StringId IN (@str0, @str1, ...) -- if more than one value1 a1 q( u+ v* L  A0 K- Y2 k5 q1 s
但简短的版本:删除括号。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则