更新1-13-10
我已经能够使用下面的代码找到一些成功的映射.我基本上忽略了没有映射的任何属性,然后映射它们.我希望得到关于我是否以最佳方式进行此项讨论的反馈意见.另外,我不知道如何进行单元测试这种映射.我的印象是使用AutoMapper应该有助于减轻检查每个属性的繁琐.
我已经能够使用下面的代码找到一些成功的映射.我基本上忽略了没有映射的任何属性,然后映射它们.我希望得到关于我是否以最佳方式进行此项讨论的反馈意见.另外,我不知道如何进行单元测试这种映射.我的印象是使用AutoMapper应该有助于减轻检查每个属性的繁琐.
这是我的新代码:
Mapper.CreateMap<MoveEntity,MoveEntityDto>() .ForMember(dest => dest.PrimaryOriginTransferee,opt => opt.Ignore()) .ForMember(dest => dest.PrimaryDestinationTransferee,opt => opt.Ignore()) .ForMember(dest => dest.Customer,opt => opt.Ignore()) .ForMember(dest => dest.DestinationAddress,opt => opt.Ignore()) .ForMember(dest => dest.OriginAddress,opt => opt.Ignore()) .ForMember(dest => dest.Order,opt => opt.Ignore()) .ForMember(dest => dest.Shipment,opt => opt.Ignore()) .ForMember(dest => dest.SourceSystemName,opt => opt.Ignore()); Mapper.CreateMap<ContactEntity,TransfereeEntityDto>(); Mapper.CreateMap<CustomerEntity,CustomerEntityDto>(); Mapper.CreateMap<AddressEntity,AddressEntityDto>(); Mapper.CreateMap<OrderEntity,OrderEntityDto>() .ForMember(dest => dest.OrderForwarding,opt => opt.Ignore()) .ForMember(dest => dest.Forwarder,opt => opt.Ignore()); Mapper.CreateMap<ShipmentEntity,ShipmentEntityDto>() .ForMember(dest => dest.Services,opt => opt.Ignore()); Mapper.CreateMap<ServiceEntity,ServiceEntityDto>() .ForMember(dest => dest.ServiceTypeCode,opt => opt.Ignore()) //TODO: ServiceTypeCode not being mapped,should it? .ForMember(dest => dest.SourceSystemName,opt => opt.MapFrom(src => Enum.GetName(typeof(SourceSystemName),src.SourceSystemName))); Mapper.CreateMap<OrderForwardingEntity,OrderForwardingEntityDto>(); Mapper.AssertConfigurationIsValid(); MoveEntityDto moveEntityDto = Mapper.Map<MoveEntity,MoveEntityDto>(moveEntity); moveEntityDto.PrimaryDestinationTransferee = Mapper.Map<ContactEntity,TransfereeEntityDto>(moveEntity.PrimaryDestinationTransferee); moveEntityDto.PrimaryOriginTransferee = Mapper.Map<ContactEntity,TransfereeEntityDto>(moveEntity.PrimaryOriginTransferee); moveEntityDto.Customer = Mapper.Map<CustomerEntity,CustomerEntityDto>(moveEntity.Customer); moveEntityDto.DestinationAddress = Mapper.Map<AddressEntity,AddressEntityDto>(moveEntity.DestinationAddress); moveEntityDto.OriginAddress = Mapper.Map<AddressEntity,AddressEntityDto>(moveEntity.OriginAddress); moveEntityDto.Order = Mapper.Map<OrderEntity,OrderEntityDto>(moveEntity.Order); moveEntityDto.Order.OrderForwarding = Mapper.Map<OrderForwardingEntity,OrderForwardingEntityDto>(moveEntity.Order.OrderForwarding); //moveEntityDto.Order.Forwarder = Mapper.Map<ForwarderEntity,ForwarderEntityDto>(moveEntity.Order.Forwarder); //Apparently there is no forwarder entity for an Order moveEntityDto.Shipment = Mapper.Map<ShipmentEntity,ShipmentEntityDto>(moveEntity.Shipment); moveEntityDto.Shipment.Services = Mapper.Map<ServiceEntity[],ServiceEntityDto[]>(moveEntity.Shipment.ServiceEntities);
原帖:
我是第一次尝试使用AutoMapper,以便从Bussiness对象映射到DTO.我遇到了一些我不知道如何排除故障的问题,包括以下异常:
AutoMapper.AutoMapperMappingException: Trying to map Graebel.SP.BO.MoveEntity to Graebel.SOA.Contracts.DataContracts.SP.MoveEntity.
Exception of type ‘AutoMapper.AutoMapperMappingException’ was thrown
这是我正在运行的AutoMapper代码:
public MoveEntityDto MapMoveEntityToMoveEntityDto(MoveEntity moveEntity) { Mapper.CreateMap<MoveEntity,MoveEntityDto>() .ForMember(dest => dest.PrimaryOriginTransferee,opt => opt.MapFrom(src => src.PrimaryOriginTransferee)) .ForMember(dest => dest.PrimaryDestinationTransferee,opt => opt.MapFrom(src => src.PrimaryDestinationTransferee)) .ForMember(dest => dest.Customer,opt => opt.MapFrom(src => src.Customer)) .ForMember(dest => dest.DestinationAddress,opt => opt.MapFrom(src => src.DestinationAddress)) .ForMember(dest => dest.Order,opt => opt.MapFrom(src => src.Order)) .ForMember(dest => dest.OriginAddress,opt => opt.MapFrom(src => src.OriginAddress)) .ForMember(dest => dest.Shipment,opt => opt.MapFrom(src => src.Shipment)) .ForMember(dest => dest.SourceSystemName,opt => opt.Ignore()); Mapper.AssertConfigurationIsValid(); MoveEntityDto moveEntityDto = Mapper.Map<MoveEntity,MoveEntityDto>(moveEntity); return moveEntityDto; }
这是我试图映射的DTO(MoveEntityDto):
public class MoveEntityDto { public bool IsOrderDetailPageModified { get; set; } public bool IsRoutingPageModified { get; set; } public bool IsServicePageModified { get; set; } public bool IsContentAndContainerPageModified { get; set; } public string FamilyRange { get; set; } public string Office { get; set; } public string ActivityType { get; set; } public string ActivitySubject { get; set; } public string ActivityNote { get; set; } public TransfereeEntity PrimaryOriginTransferee { get; set; } public TransfereeEntity PrimaryDestinationTransferee { get; set; } public CustomerEntity Customer { get; set; } public AddressEntity OriginAddress { get; set; } public AddressEntity DestinationAddress { get; set; } public OrderEntity Order { get; set; } public ShipmentEntity Shipment { get; set; } public string PortalId { get; set; } public string SourceSystemId { get; set; } public EnterpriseEnums.SourceSystemName SourceSystemName { get; set; } public MoveEntity() { PrimaryOriginTransferee = new TransfereeEntity(); PrimaryDestinationTransferee = new TransfereeEntity(); Customer = new CustomerEntity(); OriginAddress = new AddressEntity(); DestinationAddress = new AddressEntity(); Order = new OrderEntity(); Shipment = new ShipmentEntity(); } public bool HasShipment() { if (Shipment.ExternalShipmentId > 0) { return true; } return false; } }
这是我想要映射的业务对象(MoveEntity)
public class MoveEntity { public int SourceId { get; set; } public int MoveId { get; set; } public bool IsOrderDetailPageModified { get; set; } // TODO: Internal - Remove from data contract public bool IsRoutingPageModified { get; set; } // TODO: Internal - Remove from data contract public bool IsServicePageModified { get; set; } // TODO: Internal - Remove from data contract public bool IsContentAndContainerPageModified { get; set; } // Rmove from data contract public string FamilyRange { get; set; } // TODO: Is this being used? public string Office { get; set; } public string ActivityType { get; set; } public string ActivitySubject { get; set; } public string ActivityNote { get; set; } public ContactEntity PrimaryOriginTransferee { get; set; } public ContactEntity PrimaryDestinationTransferee { get; set; } public CustomerEntity Customer { get; set; } public AddressEntity OriginAddress { get; set; } public AddressEntity DestinationAddress { get; set; } public OrderEntity Order { get; set; } public ShipmentEntity Shipment { get; set; } public string CreatedBy { get; set; } public DateTime CreatedDate { get; set; } public string ModifiedBy { get; set; } public DateTime ModifiedDate { get; set; } public string SourceSystemId { get; set; } public string SourceSystemName { get; set; } public string Version { get; set; } public string PortalId { get; set; } public MoveEntity() { PrimaryOriginTransferee = new ContactEntity { ContactTypeId = ContactEntity.ContactType.PrimaryOriginationTransferee }; PrimaryDestinationTransferee = new ContactEntity { ContactTypeId = ContactEntity.ContactType.PrimaryDestinationTransferee }; OriginAddress = new AddressEntity { AddressTypeId = AddressEntity.AddressType.Origination }; DestinationAddress = new AddressEntity { AddressTypeId = AddressEntity.AddressType.Destination }; Order = new OrderEntity(); Customer = new CustomerEntity(); Shipment = new ShipmentEntity(); } public bool HasShipment() { if (Shipment.ShipmentId > 0) { return true; } return false; } }
每个类中的属性几乎完全匹配名称,但它们的类型是不同的.因此,我尝试使用“MapFrom”表达式执行自定义映射.但是,AutoMapper似乎无法让我在没有抱怨的情况下从一种对象类型指向另一种对象类型.
.ForMember(dest => dest.PrimaryOriginTransferee.Email,opt => opt.MapFrom(src => src.PrimaryOriginTransferee.Email))
但是,在尝试此操作时,我收到以下异常:
must resolve to top-level member.
Parameter name: lambdaExpression.
我一直在寻找AutoMapper可用的文档很难理解.有人可以指出我正确的方向如何正确使用此实用程序?
在此先感谢您的帮助!
亚当
解决方法
我终于得到了自己的工作.我最终使用的代码发布在下面.以正确的顺序创建对象的地图被证明是重要的.我通过这件事学到了很多东西.
我已经将我的映射组织到一个配置文件中,我不会进入这里,只要说如果你可以在继承自AutoMapper Profile类的类之外使用我的例子,你将需要使用Mapper.CreateMap代替只是创建地图.
private void CreateMaps() { CreateMap<ContactEntity,TransfereeEntityDto>(); //ContactEntity Mapping CreateMap<ContactEntity,TransfereeEntityDto>(); //CustomerEntity Mapping CreateMap<CustomerEntity,CustomerEntityDto>(); //AddressEntity Mapping CreateMap<AddressEntity,AddressEntityDto>(); //ServiceEntity Mapping CreateMap<ServiceEntity,ServiceEntityDto>() .ForMember(dto => dto.ServiceTypeCode,opt => opt.MapFrom(source => source.TypeCode)) .ForMember(dto => dto.ServiceDescriptionCode,opt => opt.MapFrom(source => source.DescriptionCode)) .ForMember(dest => dest.SourceSystemName,opt => opt.ResolveUsing<SourceSystemNameResolver>().FromMember(entity => entity.SourceSystemName)); //VehicleEntity Mapping CreateMap<VehicleEntity,VehicleEntityDto>() .ForMember(dest => dest.SourceSystemName,opt => opt.ResolveUsing<SourceSystemNameResolver>().FromMember(entity => entity.SourceSystemName)) .ForMember(dto => dto.PortalId,option => option.Ignore()); //TODO: Should PortalID be mapped to anything? It is not in the entity. //ContentEntity Mapping CreateMap<ContentEntity,ContentEntityDto>() .ForMember(dest => dest.SourceSystemName,opt => opt.ResolveUsing<SourceSystemNameResolver>().FromMember(entity => entity.SourceSystemName)); //OrderForwardingEntity Mapping CreateMap<OrderForwardingEntity,OrderForwardingEntityDto>(); //ContainerEntity Mapping CreateMap<ContainerEntity,ContainerEntityDto>() .ForMember(dest => dest.SourceSystemName,opt => opt.ResolveUsing<SourceSystemNameResolver>().FromMember(entity => entity.SourceSystemName)); //ShipmentForwardingEntity Mapping CreateMap<ShipmentForwardingEntity,ShipmentForwardingEntityDto>(); //ShipmentRouting Mapping CreateMap<ShipmentRoutingEntity,ShipmentRoutingEntityDto>(); //ShipmentEntity Mapping CreateMap<ShipmentEntity,ShipmentEntityDto>() .ForMember(dest => dest.SourceSystemName,opt => opt.ResolveUsing<SourceSystemNameResolver>().FromMember(entity => entity.SourceSystemName)) .ForMember(dto => dto.Services,option => option.MapFrom(source => source.ServiceEntities)); //Forwarder mapping CreateMap<ContactEntity,ForwarderEntityDto>(); //TODO: This property doesn't have any properties in the data contract //OrderEntity Mapping CreateMap<OrderEntity,OrderEntityDto>() .ForMember(dest => dest.SourceSystemName,opt => opt.ResolveUsing<SourceSystemNameResolver>().FromMember(entity => entity.SourceSystemName)); //.ForMember(dto => dto.Forwarder,option => option.MapFrom(entity=>entity.Forwarder) //MoveEntityMapping CreateMap<MoveEntity,MoveEntityDto>() .ForMember(dto => dto.SourceSystemName,opt => opt.ResolveUsing<SourceSystemNameResolver>().FromMember(entity => entity.SourceSystemName)); }