2010-01-12 5 views
6

Mise à jour 1-13-10 J'ai réussi à trouver le succès en utilisant le code ci-dessous pour le mappage. J'ignore essentiellement les propriétés qui n'ont pas de mappage et les mappage par la suite. J'aimerais savoir si je m'y prends le mieux possible. En outre, je ne suis pas sûr de savoir comment procéder pour tester cette cartographie. J'avais l'impression que l'utilisation de l'AutoMapper devrait aider à réduire la fastidieuse vérification de chaque propriété.Automapper Exception de mappage personnalisée

Voici mon nouveau code:

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); 

Original Post:

Je tente d'utiliser AutoMapper pour la première fois pour la carte à partir d'un objet Bussiness à un DTO. Je courais sur les questions que je ne sais pas comment résoudre, y compris l'exception suivante:

AutoMapper.AutoMapperMappingException: Essayer de carte Graebel.SP.BO.MoveEntity à Graebel.SOA.Contracts.DataContracts.SP. MoveEntity. Exception de type 'AutoMapper.AutoMapperMappingException' a été jeté

Voici le code AutoMapper que je suis en cours d'exécution:

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; 
    } 

Voici le DTO (MoveEntityDto) que je tente de la carte:

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; 
    } 
} 

est ici l'objet d'affaires (MoveEntity) que je suis en train de la carte de

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; 
    } 
} 

Les propriétés de chaque classe correspondent presque parfaitement par nom, mais leurs types sont différents. Par conséquent, j'ai essayé d'effectuer un mappage personnalisé en utilisant l'expression "MapFrom". Cependant, AutoMapper ne semble pas pouvoir me permettre de pointer d'un type d'objet à un autre sans me plaindre.

J'ai également essayé de mapper la propriété propriété-à-propriété, sans chance. Il avait l'air quelque chose comme ceci:

.ForMember(dest => dest.PrimaryOriginTransferee.Email, opt => opt.MapFrom(src => src.PrimaryOriginTransferee.Email)) 

Cependant, en essayant cela, je reçois la exeception suivante:

doit résoudre à un membre de haut niveau. Nom du paramètre: lambdaExpression.

J'ai trouvé la documentation disponible pour AutoMapper difficile à suivre. Quelqu'un peut-il me diriger dans la bonne direction quant à la façon d'utiliser cet utilitaire correctement?

Merci d'avance pour toute aide!

Adam

+0

Mur O Texte ....: ~ ( –

+2

La prochaine fois je m'assurerai qu'il n'y a pas assez d'informations Merci pour votre contribution – letsgetsilly

+0

Lolz :) :) :) :) –

Répondre

5

J'ai finalement fini par obtenir ceci pour travailler tout seul. Le code que j'ai fini par utiliser est posté ci-dessous. Créer la carte des objets dans le bon ordre s'est avéré être important. J'ai beaucoup appris en luttant contre cette chose. J'ai organisé mes mappages dans un profil, que je ne vais pas aborder ici, il suffit de dire que si vous pouvez utiliser mon exemple en dehors d'une classe héritant de la classe AutoMapper Profile, vous voudrez utiliser Mapper.CreateMap au lieu de créer simplement une carte.

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)); 

    } 
1

Vous devez ajouter des configurations de cartographie pour les types de propriétés où le type de propriété cible est différent type de propriété de destination.

Mapper.CreateMap<ContactEntity, TransfereeEntity>(); 
4

Je sais que vous avez déjà ce travail, mais je vais jeter cela là-bas au cas où d'autres personnes débarqueraient ici. Dans AutoMapper, lorsque vous avez des objets imbriqués qui doivent être mappés, même s'ils sont exactement identiques (par exemple, une classe de contrat et une classe de modèle qui correspondent), vous devez définir des mappes pour les classes enfants, puis Lorsque vous définissez la carte pour le parent, dans l'option '.ForMember' vous pouvez utiliser ces mappes enfants pour mapper le parent. Je sais que cela peut sembler confus mais un exemple le rendra clair.

Supposons que vous avez les éléments suivants:

namespace Contracts.Entities 
{ 
    public class Person 
    { 
     public string FirstName {get; set;} 

     public string LastName {get; set;} 

     public Address Address {get; set;}   
    } 

    public class Address 
    { 
     public string Street {get; set;} 

     public string City {get; set;} 

     public string State {get; set;}   
    } 
} 

namespace Model.Entities 
{ 
    public class Person 
    { 
     public string FirstName {get; set;} 

     public string LastName {get; set;} 

     public Address Address {get; set;}   
    } 

    public class Address 
    { 
     public string Street {get; set;} 

     public string City {get; set;} 

     public string State {get; set;}   
    } 
} 

Ensuite, vous allez définir les cartes suivantes:

Mapper.CreateMap<Contracts.Entities.Person, Model.Entities.Person>(); 
    Mapper.CreateMap<Contracts.Entities.Address, Model.Entities.Address>(); 

Vous pouvez penser que AutoMapper connaîtrait d'utiliser la carte d'adresse lors du mappage d'un contrat personne à une personne modèle, mais ce n'est pas le cas. Au lieu de cela, voici ce que vous avez à faire:

 Mapper.CreateMap<Contracts.Entities.Person, Model.Entities.Person>() 
        .ForMember(dest => dest.Address, opt => opt.MapFrom(src => Mapper.Map<Contracts.Entities.Address, Model.Entities.Address>(src.Address))); 

Mapper.CreateMap<Contracts.Entities.Address, Model.Entities.Address>(); 

Donc, dans votre cas, vous pouvez définir une carte Mapper.CreateMap<ContactEntity,TransfereeEntity>() puis appelez cette carte de la même manière que l'adresse ci-dessus lors de la définition de la carte pour PrimaryOriginTransferee. C'EST À DIRE.

Mapper.CreateMap<MoveEntity, MoveEntityDto>() 
.ForMember(dest => dest.PrimaryOriginTransferee , opt => opt.MapFrom(src => Mapper.Map<ContactEntity,TransfereeEntity>(src.PrimaryOriginTransferee))); 

Espérons que cela aide quelqu'un!

Questions connexes