我正在尝试使用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'附近的语法不正确。
我一定是做错了,但我不确定是什么。请告诉我我犯的是什么样的白痴。谢谢!
答案 0 :(得分:1)
问题在于使用字节数组,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数组来解决它。