【问题标题】:Mapping a custom object to multiple columns by type handler in Dapper通过 Dapper 中的类型处理程序将自定义对象映射到多个列
【发布时间】:2019-09-10 06:19:37
【问题描述】:

我遇到了一个在这里多次讨论过的问题,但不幸的是,没有一个答案或提示对我有用。

我想使用不同的自定义类型(例如货币或记录链接)。

在数据库中,我会将这些自定义类型的不同属性存储到多个列中(例如 Money:YearlyIncome.Amount、YearlyIncome.CurrencyCode)。

我发现的所有提示都试图在查询中使用“spliton”来解决问题。 但我更喜欢使用类型处理程序的解决方案,因此我不必手动将其添加到每个查询中。

我已经尝试使用属性之间的一种分隔符将信息存储在单个数据库列中。这基本上可以使用自定义类型处理程序正常工作 - 但最后的数据库看起来“丑陋”。

public class Recordlink
{
    public Guid Id { get; set; }
    public string Type { get; set; }
    public string Name { get; set; }
    ...
}

public class Money
{
    public decimal Amount { get; set; }
    public string CurrencyCode { get; set; }
    ...
}

public class Contact
{
    Guid Id {get;set;}
    Money YearlyIncome {get;set;}
    Recordlink Company {get;set;}
}

我希望在查询联系人列表时实现这一点,例如,我只能访问属性contacts[0].Company.Id(当然还有之前的NULL 检查)。

由于对类似问题有太多不同的提示和答案,我不确定这是否可能。

但即使这不可能如我所愿 - 我更愿意知道这一点,而不是寻找解决方案的年龄。

感谢和问候

马库斯

【问题讨论】:

    标签: c# multiple-columns dapper custom-type typehandler


    【解决方案1】:

    据我所知,您无法按照您在此处概述的方式执行此操作。

    标准的自定义类型处理程序如下所示:

    public class MyTypeHandler : SqlMapper.TypeHandler<MyType>
    {
        public override MyType Parse(object value)
        {
            return ...;
        }
    
        public override void SetValue(System.Data.IDbDataParameter parameter, MyType value)
        {
            parameter.Value = ...;
        }
    }
    

    因此,Parse 方法将结果行中的一项映射到您的自定义类型。 SetValue 方法将您的自定义类型的一个实例映射到一个数据库参数。将结果行的多个项目映射到一个对象不是可能性的一部分。

    在您的情况下,我不会发明自己的属性表示,而是将Money 序列化为JSON 并将其保存在表格的一列中。您可以为此制作一个自定义处理程序。

    可能看起来像这样:

    public class MoneyTypeHandler : SqlMapper.TypeHandler<Money>
    {
        public override Money Parse(Type destinationType, object value)
        {
            return JsonConvert.DeserializeObject(value.ToString(), destinationType);
        }
    
        public override void SetValue(IDbDataParameter parameter, Money value)
        {
            parameter.Value = (value == null) ? (object)DBNull.Value : JsonConvert.SerializeObject(value);
            parameter.DbType = DbType.String;
        }
    }
    

    【讨论】:

    • 感谢您的回答。首先我很高兴知道,这不可能像我想的那样——所以我不必花更多时间来尝试这个。在这种情况下,我认为我需要使用您对 json-string 的想法。它仍然不是数据库中的“好”结果,但至少它是一种存储信息的结构化方式。不幸的是,我遇到了下一个问题——这似乎是一个已知的错误,在插入/更新操作期间没有调用类型处理程序的“SetValue”方法。我刚刚做了我的第一次测试,在它工作正常的地方解析数据。有什么想法吗?
    • 不,我没有听说过这个错误,所以没有想法,抱歉。
    • 如果我想在不使用 JSON 序列化的情况下将其拆分为多个列怎么办?例如DTO 具有Address 类型的Address 属性(这是ValueObject),我想拆分名为:[Address.Country]、[Address.City]、[Address.Street] 等的列。
    • @Sergio:这听起来像是最初的问题。不使用 spliton 是不可能的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    • 1970-01-01
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多