【问题标题】:C# Merge objects with automapperC# 使用自动映射器合并对象
【发布时间】:2018-03-28 14:24:46
【问题描述】:

我的问题类似于this question,只是我需要合并更深层次。

我有两个相同类型的相似对象。我需要将这些合并为最终结果。一个对象填充了来自更可靠来源的数据,而另一个对象则更完整。我的最终结果应该包含来自更可靠来源的所有值。但是,当可靠来源中不存在某个值时,应该从更完整的来源中填充它。

我的对象看起来像这样(简化):

public class Body {
    int Id
    Client Client
    Details Details
}

public class Client {
    int Id
    Name Name
    Address Address
}

public Name {
    string FirstName
    string LastName
    etc...
}

public class Address {
    string StreetName
    string HouseNumber
    etc...
}

public class Details {
    Details1 Details1
    Details2 Details2
    many more classes which contains more nested classes...
}

所以,我发现我可以使用 AutoMapper Condition 选项来指定只映射目标类中的空值。

Mapper.CreateMap<Body, Body>()
            .ForAllMembers(opt => opt.Condition(dest => dest.DestinationValue == null));
Mapper.Map(completeObject, reliableObject);

ForAllMembers 仅适用于该类的直接子成员。所以上面的语句只会检查reliableObject中的Id, Client en Details字段是否为空。它不会检查架构中更深层次的值,例如reliableObject.Client.Address.StreetName

为了实现这一点,我必须为我的架构中的每个类配置Condition 选项,这很多,并分别映射它们。

有没有办法告诉 AutoMapper 将此条件应用于架构的每个级别? AutoMapper 甚至是合并这些对象的最佳方式吗?

我正在使用 AutoMapper 3.2.1 版。

【问题讨论】:

    标签: c# automapper


    【解决方案1】:

    在较新版本的 AutoMapper 中,Profile.AddConditionalMapper() 允许您定义全局约定,但在版本 3 中这是不可能的。

    但是,您可以做一个通用方法,例如:

    public void MapIfDestinationIsNull<T>()
    {
        Mapper.CreateMap<T, T>().ForAllMembers(opt => opt.Condition(dest => dest.DestinationValue == null));
    }
    

    然后用你所有的类型来调用它。代码行数一样多,但每行更短。

    或者,如果您有办法将所有类型放入一个数组中(例如,您有一个包含所有类型的单独程序集,或者它们有某种公共接口/基类),您可以使用反射来调用此方法你所有的类型:

    foreach (var type in types)
    {
        GetType().GetMethod("MapIfDestinationIsNull").MakeGenericMethod(type).Invoke(this, new object[] { });
    }
    

    不过,我能给您的最佳建议是简单地升级您的 AutoMapper,但如果这不可能,那么您将不得不进行一些反思。您还可以查看 AutoMapper 的源代码,看看新版本是如何做这些事情的,然后简单地模仿一下。

    【讨论】:

    • 谢谢弗雷德!我无法升级 Automapper(大公司 blabla),但我一定会尝试您对通用方法的建议。
    猜你喜欢
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多