[英]Automapper - Multi object source and one destination
I am using auto mapper to map multiple objects (db class into ui objects).我正在使用自动映射器来映射多个对象(db 类到 ui 对象)。
Map 1:地图1:
Mapper.CreateMap<sourceone, destination>().ForMember(sss => sss.one, m => m.MapFrom(source => source.abc));
Map 2:地图2:
Mapper.CreateMap<sourcetwo, destination>().ForMember(sss => sss.two, m => m.MapFrom(source => source.xyz));
destination d = new destination();
//Map 1 //地图1
d = AutoMapper.Mapper.Map<sourceone, destination>(sourceone);
//Map 2 //地图2
d = AutoMapper.Mapper.Map<sourcetwo, destination>(sourcetwo);
Once I make call to the 'Map 2', the values that are populated using Map 1 are lost.. (ie destination.one is becoming empty).一旦我调用“地图 2”,使用地图 1 填充的值就会丢失..(即destination.one 变为空)。 How do I fix this?
我该如何解决?
Map
has an overload that takes a source and destination object: Map
有一个带有源和目标对象的重载:
d = AutoMapper.Mapper.Map<sourceone, destination>(sourceone);
/* Pass the created destination to the second map call: */
AutoMapper.Mapper.Map<sourcetwo, destination>(sourcetwo, d);
mapper.MergeInto<PersonCar>(person, car)
with the accepted answer as extension-methods, simple and general version:将接受的答案作为扩展方法,简单和通用版本:
public static TResult MergeInto<TResult>(this IMapper mapper, object item1, object item2)
{
return mapper.Map(item2, mapper.Map<TResult>(item1));
}
public static TResult MergeInto<TResult>(this IMapper mapper, params object[] objects)
{
var res = mapper.Map<TResult>(objects.First());
return objects.Skip(1).Aggregate(res, (r, obj) => mapper.Map(obj, r));
}
after configuring mapping for each input-type:为每个输入类型配置映射后:
IMapper mapper = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Person, PersonCar>();
cfg.CreateMap<Car, PersonCar>();
}).CreateMapper();
public class Person
{
public string Name { get; set; }
public string PhNo { get; set; }
}
public class Company
{
public int EmpNo { get; set; }
public string Title { get; set; }
}
public class PersonCompany
{
public string Name { get; set; }
public string PhNo { get; set; }
public int EmpNo { get; set; }
public string Title { get; set; }
}
//you can test as below
var pMap = Mapper.CreateMap<Person,PersonCompany>();
pMap.ForAllMembers(d => d.Ignore());
pMap.ForMember(d => d.Name, opt => opt.MapFrom(s => s.Name))
.ForMember(d => d.PhNo, opt => opt.MapFrom(s => s.PhNo));
var cMap = Mapper.CreateMap<Company, PersonCompany>();
cMap.ForAllMembers(d => d.Ignore());
cMap.ForMember(d => d.EmpNo, opt => opt.MapFrom(s => s.EmpNo))
.ForMember(d => d.Title, opt => opt.MapFrom(s => s.Title));
var person = new Person { Name = "PersonName", PhNo = "212-000-0000" };
var personCompany = Mapper.Map<Person,PersonCompany>(person);
var company = new Company { Title = "Associate Director", EmpNo = 10001 };
personCompany = Mapper.Map(company, personCompany);
Console.WriteLine("personCompany.Name={0}", personCompany.Name);
Console.WriteLine("personCompany.PhNo={0}", personCompany.PhNo);
Console.WriteLine("personCompany.EmpNo={0}", personCompany.EmpNo);
Console.WriteLine("personCompany.Title={0}", personCompany.Title);
According to me you should avoid calling the overloaded Map method taking an instance of the destination object as explained in the accepted answer.根据我的说法,您应该避免调用重载的 Map 方法来获取目标对象的实例,如已接受的答案中所述。 This won't let you test/validate your mapping configuration (
Mapper.Configuration.AssertConfigurationIsValid()
) or to do so you will add a lot of 'Ignore' in your mappings.这不会让您测试/验证您的映射配置(
Mapper.Configuration.AssertConfigurationIsValid()
),否则您将在映射中添加很多“忽略”。
A very simple solution is to create a composite type holding source references and define your mapping to the destination based on that composite type.一个非常简单的解决方案是创建一个包含源引用的复合类型,并根据该复合类型定义到目标的映射。
Something like:就像是:
public class SourceOneTwo
{
public SourceOne SourceOne { get; set; }
public SourceTwo SourceTwo { get; set; }
}
static void Main(string[] args)
{
var config = new MapperConfiguration(cfg =>
cfg.CreateMap<SourceOneTwo, Destination>()
.ForMember(dest => dest.one, m => m.MapFrom(source => source.SourceOne.abc))
.ForMember(dest => dest.two, m => m.MapFrom(source => source.SourceTwo.xyz)));
config.AssertConfigurationIsValid();
}
现在看起来是这样的:
DestinationDto = _mapper.Map(source2, _mapper.Map<source1type, destinationType>(source1));
Just wanted to add, that these days you can make use of tuple syntax to define mapping from multiple types.只是想补充一点,现在您可以使用元组语法来定义多种类型的映射。
// configuring
Mapper
.CreateMap<(SourceType1 Source1, SourceType2 Source2), DestinationType>()
.ForMember(sss => sss.one, m => m.MapFrom(source => source.Source1.abc))
.ForMember(sss => sss.two, m => m.MapFrom(source => source.Source2.xyz));
// using
var result = Mapper.Map<DestinationType>((source1, source2));
Pros:优点:
Cons:缺点:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.