Reputation: 1648
I'm trying to use Dapper's (v1.42) support for automatic expansion of query parameters for IN clauses. My query looks like:
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 } }
);
But that results in System.Data.SqlClient.SqlException (0x80131904): Incorrect syntax near '@byteVals'.
I must be doing something wrong, but I'm not sure what. Please tell me what sort of idiocy I'm committing. Thank you!
Upvotes: 1
Views: 1223
Reputation: 2329
The issue is with the use of the byte array, Dapper will always pass byte arrays as a single binary value - the fact that the query text has an "IN" clause does not change that (see the comment from @Damien_The_Unbeliever).
To illustrate, the following works (based on the NORTHWND database, since I had that to hand) because the parameter expansion is working with an int array -
var results = db.Query<Product>(
"SELECT * FROM Products WHERE ProductId IN @ids",
new
{
ids = new [] { 1, 2 } // This works (int array)
}
);
.. but the following fails, where it tries to pass a byte array -
var results = db.Query<Product>(
"SELECT * FROM Products WHERE ProductId IN @ids",
new
{
ids = new byte[] { 1, 2 } // This fails (byte array)
}
);
Using SQL profiler, the first int-array approach results in the following query:
exec sp_executesql
N'SELECT * FROM Products WHERE ProductId IN (@ids1,@ids2)',
N'@ids1 int,@ids2 int',
@ids1=1,
@ids2=2
You can clearly see the individual parameters being passed over.
The byte-array approach results in the following query:
exec sp_executesql
N'SELECT * FROM Products WHERE ProductId IN @ids',
N'@ids varbinary(2)',
@ids=0x0102
Here, the "@ids" parameter is passed as a single value, rather than being expanded into individual ones - this is what is causing your problem.
You should be able to work around it by using your byte values to populate an int array.
Upvotes: 1