我正在尝试使用 Dapper 的 (v1.42) 支持来自动扩展 IN 子句的查询参数。我的查询如下所示:
var records = db.Query(
"SELECT [IdCol], [OtherCol], [TinyIntCol], [TextCol] FROM [Tbl] WHERE [FilterCol] = @filterVal AND [TinyIntCol] IN @byteVals",
new { filterVal = ..., byteVals = flag ? new byte[] { Constants.Byte1, Constants.Byte2 } : new byte[] { Constants.Byte1 } }
);
但这会导致System.Data.SqlClient.SqlException(0x80131904):"@byteVals"附近的语法不正确。
我一定做错了什么,但我不确定是什么。请告诉我我犯了什么样的白痴。谢谢!
问题是使用字节数组时,Dapper 将始终将字节数组作为单个二进制值传递 - 查询文本具有"IN"子句的事实不会改变这一点(请参阅@Damien_The_Unbeliever的评论)。
为了说明,以下工作(基于 NORTHWND 数据库,因为我手头有它),因为参数扩展正在使用 int 数组 -
var results = db.Query<Product>(
"SELECT * FROM Products WHERE ProductId IN @ids",
new
{
ids = new [] { 1, 2 } // This works (int array)
}
);
.. 但是以下内容失败了,它试图传递一个字节数组 -
var results = db.Query<Product>(
"SELECT * FROM Products WHERE ProductId IN @ids",
new
{
ids = new byte[] { 1, 2 } // This fails (byte array)
}
);
使用 SQL 探查器,第一个 int-array 方法会产生以下查询:
exec sp_executesql
N'SELECT * FROM Products WHERE ProductId IN (@ids1,@ids2)',
N'@ids1 int,@ids2 int',
@ids1=1,
@ids2=2
您可以清楚地看到被传递的各个参数。
字节数组方法会产生以下查询:
exec sp_executesql
N'SELECT * FROM Products WHERE ProductId IN @ids',
N'@ids varbinary(2)',
@ids=0x0102
在这里,"@ids"参数作为单个值传递,而不是扩展为单个值 - 这就是导致问题的原因。
您应该能够通过使用字节值填充 int 数组来解决此问题。