当IN子句的值列表来自业务逻辑时,使用Dapper ORM编写带有IN子句的查询的最佳方法是什么?例如,假设我有一个查询:

SELECT * 
  FROM SomeTable 
 WHERE id IN (commaSeparatedListOfIDs)

commaSeparatedListOfIDs是从业务逻辑传入的,它可以是任何类型的IEnumerable(Integer)。在这种情况下如何构造查询?我是否需要做我目前所做的基本上是字符串连接还是有一些我不知道的高级参数映射技术?


当前回答

还要确保你没有像这样用圆括号括起你的查询字符串:

SELECT Name from [USER] WHERE [UserId] in (@ids)

我使用Dapper 1.50.2导致SQL语法错误,通过删除括号来修复

SELECT Name from [USER] WHERE [UserId] in @ids

其他回答

不需要像在常规SQL中那样在WHERE子句中添加()。因为达普会自动帮我们做。语法如下:-

const string SQL = "SELECT IntegerColumn, StringColumn FROM SomeTable WHERE IntegerColumn IN @listOfIntegers";

var conditions = new { listOfIntegers };
    
var results = connection.Query(SQL, conditions);

postgres的示例:

string sql = "SELECT * FROM SomeTable WHERE id = ANY(@ids)"
var results = conn.Query(sql, new { ids = new[] { 1, 2, 3, 4, 5 }});

根据我的经验,处理这个问题最友好的方法是使用一个函数将字符串转换为值表。

在网络上有很多可用的分配器函数,如果你喜欢SQL,你很容易就能找到一个。

然后你可以做…

SELECT * FROM table WHERE id IN (SELECT id FROM split(@list_of_ids))

Or

SELECT * FROM table INNER JOIN (SELECT id FROM split(@list_of_ids)) AS list ON list.id = table.id

(或相似的)

直接从GitHub项目主页:

Dapper允许您传入IEnumerable,并将自动参数化您的查询。

connection.Query<int>(
    @"select * 
      from (select 1 as Id union all select 2 union all select 3) as X 
      where Id in @Ids", 
    new { Ids = new int[] { 1, 2, 3 });

将译为:

select * 
from (select 1 as Id union all select 2 union all select 3) as X 
where Id in (@Ids1, @Ids2, @Ids3)

// @Ids1 = 1 , @Ids2 = 2 , @Ids2 = 3
SELECT * FROM tbl WHERE col IN @val

我还注意到这种语法不适用于byte[]。Dapper只接受最后一个元素,参数必须用圆括号括起来。 然而,当我将类型更改为int[]时,一切正常。