Dapper (1.13 Noobget Package) creates different SQL statements depending on if it's used with a plain ADO.NET database connection or with a decorated mini-profiler database connection.
Example code (tested with Postgresql)
Usings:
using System.Linq;
using Dapper;
using Npgsql;
using NUnit.Framework;
using StackExchange.Profiling;
using StackExchange.Profiling.Data;
Test1 uses a plain ADO.NET connection and fails:
[TestFixture]
public class DapperTests {
private const string cnnstr = "HOST=...;DATABASE=...;USER ID=...;PASSWORD=...;";
[Test]
public void Test1() {
using (var cnn = new NpgsqlConnection(cnnstr)) {
cnn.Open();
// The following line fails:
cnn.Query<int>("SELECT 1 WHERE 42 IN @Items", new {Items = new[] {41, 42, 43}}).Single();
// Npgsql.NpgsqlException : ERROR: 42883: operator does not exist: integer = integer[]
}
}
Test2 uses a mini-profiler connection wrapped around the ADO.NET connection and succeeds:
[Test]
public void Test2() {
using (var cnn = new NpgsqlConnection(cnnstr))
using (var profiled = new ProfiledDbConnection(cnn, MiniProfiler.Start())) {
profiled.Open();
int result = profiled.Query<int>("SELECT 1 WHERE 42 IN @Items", new {Items = new[] {41, 42, 43}}).Single();
Assert.AreEqual(1, result);
}
}
}
Looking at the generated SQL it becomes clear why Test1 fails:
- SQL of Test1: SELECT 1 WHERE 42 IN ((array[41,42,43])::int4[])
- SQL of Test2: SELECT 1 WHERE 42 IN (((41)),((42)),((43)))
Arrays don't support IN.
Why does dapper generate different SQL when it's used with/without a profiled connection?
Why does it generate an array[...] with a plain connection? Due to dapper's docs it should generate a tuple: