使用automapper反规范化对象层次结构

Esb*_*ach 5 c# automapper automapper-3

我知道有些问题类似于这个问题,但据我所知(并且测试),所提供的解决方案似乎都不合适,所以这里有.

我想知道是否可以展平/非规范化对象层次结构,以便使用AutoMapper将具有嵌套属性列表的实例映射到某个目标类型的列表.

我有一个类似于的源类

资料来源:

public class DistributionInformation
{
   public string Streetname;
   public RouteInformation[] Routes;
}

public class RouteInformation
{
   public int RouteNumber;
   public string RouteDescription;
}
Run Code Online (Sandbox Code Playgroud)

目的地:

public class DenormDistributionInfo
{
   public string Streetname;
   public int RouteNumber;
   public string RouteDescription;
}
Run Code Online (Sandbox Code Playgroud)

所以我想将两个源映射到非规范化目标DenormDistributionInfo的列表.

即:

IEnumerable<DenormDistributionInfo> result = Mapper.Map(distributionInformationInstance);
Run Code Online (Sandbox Code Playgroud)

使用AutoMapper是可行/可行的,还是应该"手动"放弃和反规范?

Iai*_*way 4

最重要的是,您希望避免在映射中“查找”源中不隐式的数据。“神奇”的映射会导致严重的维护问题。

然而,从概念上讲,这种映射非常简单。唯一复杂的因素是您需要两个源对象( aDistributionInformation和 a RouteInformation)才能构造目标对象。如果你遵循这个思路,我们可以创建一个非魔法映射,清楚地保留我们的意图 - 这是我的做法:-

// We need both source objects in order to perform our map
Mapper.CreateMap<Tuple<DistributionInformation, RouteInformation>, DenormDistributionInfo>()
      .ForMember(d => d.Streetname, o => o.MapFrom(s => s.Item1.Streetname))
      .ForMember(d => d.RouteDescription, o => o.MapFrom(s => s.Item2.RouteDescription))
      .ForMember(d => d.RouteNumber, o => o.MapFrom(s  => s.Item2.RouteNumber));

// We can use ConstructUsing to pass both our source objects to our map
Mapper.CreateMap<DistributionInformation, IEnumerable<DenormDistributionInfo>>()
      .ConstructUsing(
          x => x.Routes
                .Select(y => Mapper.Map<DenormDistributionInfo>(Tuple.Create(x, y)))
                .ToList());
Run Code Online (Sandbox Code Playgroud)

并调用它:-

var flattened = Mapper.Map<IEnumerable<DenormDistributionInfo>>(source);
Run Code Online (Sandbox Code Playgroud)

如果您愿意,可以通过创建 DTO 来保存两个源对象来避免元组的一些恐怖。如果您的实际代码比您在问题中提供的示例稍微复杂一些,我特别强烈建议您这样做。

使用 AutoMapper 执行此映射是否比手动执行更复杂或更简单,由您决定。在这种情况下,我认为我不会打扰,但在更复杂且经常重复的情况下,我可能会考虑它。