gpt4 book ai didi

dapper - 为什么 Dapper 在有/没有迷你分析器连接的情况下为 Postgres 生成不同的 SQL

转载 作者:行者123 更新时间:2023-12-01 23:52:03 54 4
gpt4 key购买 nike

Dapper(1.13 Noobget 包)根据是与普通 ADO.NET 数据库连接还是与修饰的迷你分析器数据库连接一起使用,创建不同的 SQL 语句。

示例代码(使用 Postgresql 测试)

用途:

using System.Linq;
using Dapper;
using Npgsql;
using NUnit.Framework;
using StackExchange.Profiling;
using StackExchange.Profiling.Data;

Test1 使用普通的 ADO.NET 连接并且失败:

[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 使用围绕 ADO.NET 连接的迷你分析器连接,并且成功:

  [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);
}
}
}

查看生成的 SQL,就可以清楚 Test1 失败的原因:

  • Test1 的 SQL:SELECT 1 WHERE 42 IN ((array[41,42,43])::int4[])
  • 测试 2 的 SQL:SELECT 1 WHERE 42 IN (((41)),((42)),((43)))

数组不支持 IN。

为什么 dapper 在有/没有配置文件连接的情况下使用时会生成不同的 SQL?

为什么它会生成一个带有普通连接的数组[...]?由于dapper's docs它应该生成一个元组:

Dapper List Support

最佳答案

Dapper 中有一个“FeatureSupport”类,其中包含对数组进行特殊处理的设置。 Postgresql 连接被标记为支持数组,而其他连接类型(包括 MiniProfiler ProfiledDbConnections)被标记为不支持数组。

如果连接不支持数组,Dapper 会手动为数组中的每一项创建一个参数(如文档中所述) - 它会成为 SQL 中的一个元组,例如: SELECT 1 WHERE 42 IN (41, 42,43)

如果连接支持数组(如 Postgres 的 NpgsqlConnection),则数组参数将直接传递到连接,从而导致一些难看的结果,例如: SELECT 1 WHERE 42 IN ('{41,42,43}'::int4[]) - 实际上失败了,因为 IN 不支持数组。

相关代码在SqlMapper.PackListParameters方法中。

因此,在 ProfiledDbConnections 和 NpgsqlConnections 之间切换会导致问题,因为生成的 SQL 会不同。

要摆脱 Postgres 连接中的数组语法,可以使用以下代码(尽管它仅适用于全局级别...):

using Dapper;
using Npgsql;

using (var cnn = new NpgsqlConnection())
FeatureSupport.Get(cnn).Arrays = false;

似乎没有办法在每个查询或每个参数级别启用/禁用数组语法。

PS:我在 https://code.google.com/p/dapper-dot-net/issues/detail?id=107&q=postgres 发现了这个问题的问题

关于dapper - 为什么 Dapper 在有/没有迷你分析器连接的情况下为 Postgres 生成不同的 SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22561318/

54 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com