Обновление 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 Object в DTO. Я сталкиваюсь с проблемами, которые я не знаю, как устранить неполадки, включая следующее исключение:
AutoMapper.AutoMapperMappingException: попытка сопоставить Graebel.SP.BO.MoveEntity с Graebel.SOA.Contracts.DataContracts.SP.MoveEntity.
Исключение типа 'AutoMapper.AutoMapperMappingException' было сгенерировано
Вот код 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))
Однако при попытке этого я получаю следующее исключение:
должен разрешить член верхнего уровня.
Имя параметра: lambdaExpression.
Мне трудно найти доступную документацию для AutoMapper. Может кто-нибудь указать мне правильное направление относительно того, как правильно использовать эту утилиту?
Заранее спасибо за любую помощь!
Адам