除了AutoMapper中的ForMember方法之外,还有其他自定义映射方法吗?

时间:2015-07-30 21:44:41

标签: c# automapper

我有复杂的模型(SyncBillToPartyMaster),我想自定义映射到我的简单POCO类。

Mapper.CreateMap<SyncBillToPartyMaster, CustomerAddress>()
.ForMember(d => d.CustomerId, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.CustomerParty.PartyIDs.ID.Value))
.ForMember(d => d.CustomerAddressId, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.PartyIDs.ID.Value))
.ForMember(d => d.City, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.Location.Address.CityName))
.ForMember(d => d.State, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.Location.Address.CountrySubDivisionCode.Value))
.ForMember(d => d.Country, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.Location.Address.CountryCode.Value))
.ForMember(d => d.Zip, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.Location.Address.PostalCode.Value))
.ForMember(d => d.Address1, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.Location.Address.AddressLine[0].Value))
.ForMember(d => d.Address2, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.Location.Address.AddressLine[1].Value))
.ForMember(d => d.Address3, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.Location.Address.AddressLine[2].Value))
.ForMember(d => d.Phone1, o => o.MapFrom(src => GetContact(src.DataArea.BillToPartyMaster, "phone")))
.ForMember(d => d.Fax1, o => o.MapFrom(src => GetContact(src.DataArea.BillToPartyMaster, "fax")))
.ForMember(d => d.MaintenanceCustomerId, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.LastModificationPerson.IDs[0].Value))
.ForMember(d => d.MaintenanceUser, o => o.MapFrom(src => src.DataArea.BillToPartyMaster.LastModificationPerson.Name.Value))
.ForMember(d => d.MaintenanceDate, o => o.MapFrom(src => DateTime.UtcNow));

如您所见,使用AutoMapper的ForMember方法将我的复杂模型SyncBillToPartyMaster映射到CustomerAddress非常繁琐。除了使用ForMember方法之外,还有其他方法可以使它更优雅吗?

顺便说一下,除了SyncBillToPartyMaster,我还有更多,更复杂的模型。如果有另一种方法可以实现我的目标,我不想以同样的方式做同样的事情。

2 个答案:

答案 0 :(得分:13)

不要使用AutoMapper,这里没有任何匹配。你没有保存任何东西而只是使用“新”操作员并自己设置一切。

答案 1 :(得分:0)

我在Automapper中阅读了一些上下文,并找到了ITypeConverter<in T, out TU>接口,我可以在其中实现自定义映射器类并执行自定义映射。为了注册我的自定义映射器,我使用了Mapper.CreateMap<T,TU>().ConvertUsing()

这是我的自定义映射器:

public class CustomerAddressBillToPartyMasterMapper : ITypeConverter<SyncBillToPartyMaster, CustomerAddress>
    {
        public CustomerAddress Convert(ResolutionContext context)
        {
            var syncBillToPartyMaster = context.SourceValue as SyncBillToPartyMaster;

            if (syncBillToPartyMaster == null)
                return null;

            var customerAddressesSource = syncBillToPartyMaster.DataArea.BillToPartyMaster;

            return new CustomerAddress
            {
                CustomerId = customerAddressesSource.CustomerParty.PartyIDs.ID.Value,
                CustomerAddressId = customerAddressesSource.PartyIDs.ID.Value,
                City = customerAddressesSource.Location.Address.CityName,
                State = customerAddressesSource.Location.Address.CountrySubDivisionCode.Value,
                Country = customerAddressesSource.Location.Address.CountryCode.Value,
                Zip = customerAddressesSource.Location.Address.PostalCode.Value,
                Address1 = customerAddressesSource.Location.Address.AddressLine[0].Value,
                Address2 = customerAddressesSource.Location.Address.AddressLine[1].Value,
                Address3 = customerAddressesSource.Location.Address.AddressLine[2].Value,
                Phone1 = GetContact(customerAddressesSource, "phone"),
                Fax1 = GetContact(customerAddressesSource, "fax"),
                MaintenanceCustomerId = customerAddressesSource.LastModificationPerson.IDs[0].Value,
                MaintenanceUser = customerAddressesSource.LastModificationPerson.Name.Value,
                MaintenanceDate = DateTime.UtcNow
            };
        }
 }

这就是我注册的方式:

Mapper.CreateMap<SyncBillToPartyMaster, CustomerAddress>().ConvertUsing(new CustomerAddressBillToPartyMasterMapper());

我认为这比我之前发布的代码要清晰得多。