未调用 Dapper 自定义 SqlMapper.TypeHandler Parse 方法
Posted
技术标签:
【中文标题】未调用 Dapper 自定义 SqlMapper.TypeHandler Parse 方法【英文标题】:Dapper custom SqlMapper.TypeHandler Parse method not called 【发布时间】:2019-06-14 23:51:46 【问题描述】:我创建了一个 SqlMapper.TypeHandler 来将 Customer 对象映射到 CreditAccount 类,如下所示:
public class CustomerTypeHandler : SqlMapper.TypeHandler<Customer>
public override Customer Parse(object value)
throw new NotImplementedException();
public override void SetValue(IDbDataParameter parameter, Customer
value)
throw new NotImplementedException();
public class CreditAccount
public int AccountId get; set;
public Customer Customer get; set;
public class Customer
public string FirstName get; set;
public string LastName get; set;
public string MiddleName get; set;
当我连接到数据库并调用存储过程时,永远不会调用 CustomerTypeHandler Parse 方法,并且我的 CreditAccount 对象仅填充了 AccountId。 Customer 对象为空。
我这样称呼它:
public async Task<CreditAccount> GetCreditAccount(int accountId)
var sql = "MY PROC NAME HERE";
var parameters = new DynamicParameters();
parameters.Add("@AccountId", accountId);
SqlMapper.AddTypeHandler(new CustomerTypeHandler());
using (IDbConnection connection = Connection)
connection.Open();
var account = await connection.QueryFirstAsync<CreditAccount>(sql, parameters, commandType: CommandType.StoredProcedure);
return account;
我在 Parse 方法中放置了一个断点,但它从未被调用。 数据库连接正常,我正在获取 AccountId。
我的环境; .NET Core 2.2 小巧玲珑 1.50.5
代码很简单。我没有例外。有什么想法吗?
【问题讨论】:
您能否添加一些有关您的表的外观以及存储过程中的查询的更多信息? @Florian 感谢您查看我的帖子。我偶然发现了解决问题的方法。显然,在 QueryFirstAsync 调用中不会调用 CustomTypeHandler。当我使用带有 map 参数的 connection.QueryAsync 时,将调用处理程序 Parse。我不知道这是否是一个错误、一个功能,或者我不完全理解何时调用 CustomTypeHandler。谁能解释一下区别? 我通过 simplecrud .GetList 的 .Query 遇到了类似的问题。就像 hcode 说的那样,任何人都可以了解何时调用自定义类型处理程序? 【参考方案1】:一年过去了,现在 Dapper 2.0.30 中没有这个错误。 我在 Postgres 的 jsonb 列上检查了它。
using Dapper;
using Newtonsoft.Json;
using Npgsql;
using System;
using System.Data;
public class CreditAccount
public int AccountId get; set;
public Customer Customer get; set;
public class Customer
public string FirstName get; set;
public string LastName get; set;
public string MiddleName get; set;
public class CustomerJsonObjectTypeHandler : SqlMapper.TypeHandler<Customer>
public override void SetValue(IDbDataParameter parameter, Customer value)
parameter.Value = (value == null)
? (object)DBNull.Value
: JsonConvert.SerializeObject(value);
parameter.DbType = DbType.String;
public override Customer Parse(object value)
return JsonConvert.DeserializeObject<Customer>(value.ToString());
使用此类的示例 - 一切正常。
static void Main(string[] args)
using (var connection = GetDefaultConnection())
connection.Open();
var customer = new Customer
FirstName = "Gaday",
LastName = "Ivanova",
MiddleName = "Petrovich"
;
var jsonData = JsonConvert.SerializeObject(customer);
var strQuery = $"SELECT 10500 as AccountId,'jsonData'::jsonb as Customer";
SqlMapper.AddTypeHandler(new CustomerJsonObjectTypeHandler());
try
var data = connection.QueryFirst<CreditAccount>(strQuery);
catch(Exception ex)
Console.WriteLine(ex.Message);
【讨论】:
那么解决方法是什么?无法发现两者之间的主要区别 “在 Dapper 2.0.30 中没有这个错误”。新的 dapper 版本没有描述错误以上是关于未调用 Dapper 自定义 SqlMapper.TypeHandler Parse 方法的主要内容,如果未能解决你的问题,请参考以下文章