C# 使用automapper从两个项目映射

C# 使用automapper从两个项目映射,c#,automapper,C#,Automapper,在我的数据层中,我有一个存储库,可以返回如下项目列表: new List<Item> { new Item { Title = "Something", DetailId = 500 }, new Item { Title = "Whatever", DetailId = 501 }, } new List<ServiceItem> { new ServiceItem { Title = "Something", Size = "Large" }

在我的数据层中,我有一个存储库,可以返回如下项目列表:

new List<Item> {
    new Item { Title = "Something", DetailId = 500 },
    new Item { Title = "Whatever", DetailId = 501 },
}
new List<ServiceItem> {
    new ServiceItem { Title = "Something", Size = "Large" },
    new ServiceItem { Title = "Whatever", Size = "Medium" },
}
现在,在我的服务层中,我想将上面的列表映射成如下内容:

new List<Item> {
    new Item { Title = "Something", DetailId = 500 },
    new Item { Title = "Whatever", DetailId = 501 },
}
new List<ServiceItem> {
    new ServiceItem { Title = "Something", Size = "Large" },
    new ServiceItem { Title = "Whatever", Size = "Medium" },
}
新列表{
新服务项{Title=“Something”,Size=“Large”},
新服务项{Title=“Whatever”,Size=“Medium”},
}
请注意,我需要列表中的对象(
Title
)和详细对象的属性。有没有什么好方法可以用AutoMapper来映射这一点

我曾经考虑过创建一个依赖于我的存储库实例的概要文件,然后让AutoMapper执行细节请求,但是让AutoMapper获取新数据感觉有点混乱


有没有一种干净的方法可以将两个对象映射为一个对象?

本博客介绍了一种方法:。它会对每个输入对象进行一次Map()调用,但至少会将其包装在一个helper中。

一种可能是将Item和ItemDetail对象包装在一个元组中,并基于该元组定义映射。映射代码看起来像这样

Mapper.CreateMap<Tuple<Item, ItemDetail>, ServiceItem>()
    .ForMember(d => d.Title, opt => opt.MapFrom(s => s.Item1.Title))
    .ForMember(d => d.Size, opt => opt.MapFrom(s => s.Item2.Size));
Mapper.CreateMap<Item, ServiceItem>()
    .ForMember(d => d.Size, opt => opt.MapFrom(s => itemDetails.Where(x => s.DetailId == x.Id).First().Size));
Mapper.CreateMap()
.ForMember(d=>d.Title,opt=>opt.MapFrom(s=>s.Item1.Title))
.ForMember(d=>d.Size,opt=>opt.MapFrom(s=>s.Item2.Size));
您必须自己加入正确的项目和项目详细信息。如果希望Automapper也将项与正确的ItemDetail匹配,则需要更改映射,以便在大小解析期间,Automapper执行查找并返回匹配的大小。代码看起来像这样

Mapper.CreateMap<Tuple<Item, ItemDetail>, ServiceItem>()
    .ForMember(d => d.Title, opt => opt.MapFrom(s => s.Item1.Title))
    .ForMember(d => d.Size, opt => opt.MapFrom(s => s.Item2.Size));
Mapper.CreateMap<Item, ServiceItem>()
    .ForMember(d => d.Size, opt => opt.MapFrom(s => itemDetails.Where(x => s.DetailId == x.Id).First().Size));
Mapper.CreateMap()
.ForMember(d=>d.Size,opt=>opt.MapFrom(s=>itemDetails.Where(x=>s.DetailId==x.Id).First().Size));

此映射使用Automapper的自动映射功能将Item.Title映射到ServiceItem.Title。映射正在使用IEnumerable命名的itemDetails来查找匹配项,但是应该可以用数据库调用来替换它。现在,由于我不认为Autmapper设计用于执行这种类型的查找,所以对于大量项目来说,性能可能不是那么好。这是需要测试的。

使用ValueInjector而不是AutoMapper,它很容易在两者之间切换,并且ValueInjector支持从多个源即时注入值

serviceItem.InjectFrom(item);
serviceItem.InjectFrom(itemDetail);

作为奖励,您不必像使用AutoMapper那样进行所有静态映射

是的,这些或多或少都是我自己可以想到的选项。这不完全是我所希望的,但至少我没有忽略一些显而易见的东西,这让我感到放心:-)谢谢你-事实上,我不知道AutoMapper也可以填充现有的对象。但在这种情况下,我选择了Rich下面的建议。