Npgsql 3.0.0 在 Dapper 1.42 中使用具有自定义类型处理程序的参数的查询阻塞
Npgsql 3.0.0 Chokes on Queries with Parameters that have Custom Type Handlers in Dapper 1.42
这个问题似乎与 Npgsql 3.0.0 中的某些内容有关,该内容在 Dapper 1.42 下发生了变化。我得出这个结论是因为以下代码曾经在使用 Npgsql 2.2.3 和相同版本的 Dapper 时起作用:
public struct MyStruct
{
private readonly int _val;
public MyStruct(int i) { _val = i; }
public int MyInt { get { return _val; } }
}
public class MyStructHandler : SqlMapper.TypeHandler<MyStruct>
{
public override MyStruct Parse(object value)
{
if (value is int)
{
return new MyStruct((int)value);
}
throw new FormatException("Invalid Conversion to MyStruct");
}
public override void SetValue(IDbDataParameter parameter, MyStruct value)
{
parameter.DbType = DbType.Int32;
parameter.Value = value.MyInt;
}
}
public static int Main()
{
var myStructHandler = new MyStructHandler();
SqlMapper.AddTypeHandler(myStructHandler);
const string query = "SELECT * FROM MyTable WHERE ID = :someID";
var queryParams = new DynamicParameters();
queryParams.Add("someID", new MyStruct(3));
IDbConnection connection = new NpgsqlConnection(connectionString);
var result = connection.Execute(query, queryParams);
}
当我运行上面的代码时,我得到一个异常信息:
Problem with query: SELECT * FROM MyTable WHERE ID = :someID
The given key was not present in the dictionary
System.Collections.Generic.KeyNotFoundException : The given key was not present in the dictionary.
我已验证以下内容:
1) Passing in parameters of built-in types works correctly. E.g., if I change the line queryParams.Add("someID", new MyStruct(3));
to queryParams.Add("someID", 3);
, the query returns as expected.
2) MyStructHandler.Parse works correctly when deserializing a field of type MyStruct
3) The parameter name and casing matches between the query and the DynamicParams object
4) MyStructHandler.SetValue is NEVER called prior to throwing the exception
这个错误似乎是新引入的,并且似乎只影响 类 自定义 Dapper 处理程序。有谁知道为什么我升级到 Npgsql 3.0.0 后它停止工作,更重要的是,如何修复它?
-- 附加信息 --
在 Npgsql.NpgsqlParameter.set_DbType(DbType value) 中抛出异常,其中调用了 System.Collections.Generic.Dictionary`2.get_Item(TKey key)。同样,这曾经在 Npgsql 2.2.3 中工作,所以我假设该代码中的某些更改破坏了这个用例。
此问题已报告并已修复,请参阅 https://github.com/npgsql/npgsql/issues/694
您可以获取一个不稳定的 nuget 包来立即解决此问题 (http://www.npgsql.org/install.html),或者再等几天,直到我们发布带有此修复程序的 Npgsql 3.0.1。
这个问题似乎与 Npgsql 3.0.0 中的某些内容有关,该内容在 Dapper 1.42 下发生了变化。我得出这个结论是因为以下代码曾经在使用 Npgsql 2.2.3 和相同版本的 Dapper 时起作用:
public struct MyStruct
{
private readonly int _val;
public MyStruct(int i) { _val = i; }
public int MyInt { get { return _val; } }
}
public class MyStructHandler : SqlMapper.TypeHandler<MyStruct>
{
public override MyStruct Parse(object value)
{
if (value is int)
{
return new MyStruct((int)value);
}
throw new FormatException("Invalid Conversion to MyStruct");
}
public override void SetValue(IDbDataParameter parameter, MyStruct value)
{
parameter.DbType = DbType.Int32;
parameter.Value = value.MyInt;
}
}
public static int Main()
{
var myStructHandler = new MyStructHandler();
SqlMapper.AddTypeHandler(myStructHandler);
const string query = "SELECT * FROM MyTable WHERE ID = :someID";
var queryParams = new DynamicParameters();
queryParams.Add("someID", new MyStruct(3));
IDbConnection connection = new NpgsqlConnection(connectionString);
var result = connection.Execute(query, queryParams);
}
当我运行上面的代码时,我得到一个异常信息:
Problem with query: SELECT * FROM MyTable WHERE ID = :someID
The given key was not present in the dictionary
System.Collections.Generic.KeyNotFoundException : The given key was not present in the dictionary.
我已验证以下内容:
1) Passing in parameters of built-in types works correctly. E.g., if I change the line
queryParams.Add("someID", new MyStruct(3));
toqueryParams.Add("someID", 3);
, the query returns as expected.
2) MyStructHandler.Parse works correctly when deserializing a field of type MyStruct
3) The parameter name and casing matches between the query and the DynamicParams object
4) MyStructHandler.SetValue is NEVER called prior to throwing the exception
这个错误似乎是新引入的,并且似乎只影响 类 自定义 Dapper 处理程序。有谁知道为什么我升级到 Npgsql 3.0.0 后它停止工作,更重要的是,如何修复它?
-- 附加信息 --
在 Npgsql.NpgsqlParameter.set_DbType(DbType value) 中抛出异常,其中调用了 System.Collections.Generic.Dictionary`2.get_Item(TKey key)。同样,这曾经在 Npgsql 2.2.3 中工作,所以我假设该代码中的某些更改破坏了这个用例。
此问题已报告并已修复,请参阅 https://github.com/npgsql/npgsql/issues/694
您可以获取一个不稳定的 nuget 包来立即解决此问题 (http://www.npgsql.org/install.html),或者再等几天,直到我们发布带有此修复程序的 Npgsql 3.0.1。