sql server - 我在 Dapper 的 IN-CLAUSE 支持方面做错了什么?



我正在尝试使用 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 数组来解决此问题。

最新更新