c# – 自动映射自定义映射异常

前端之家收集整理的这篇文章主要介绍了c# – 自动映射自定义映射异常前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
更新1-13-10
我已经能够使用下面的代码找到一些成功的映射.我基本上忽略了没有映射的任何属性,然后映射它们.我希望得到关于我是否以最佳方式进行此项讨论的反馈意见.另外,我不知道如何进行单元测试这种映射.我的印象是使用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));

    }

猜你在找的C#相关文章