如何使用 Automapper 将一个源映射到多个目的地?
How to map one source to multiple destinations using Automapper?
示例如下:
实体:
public class Contact
{
public int Id { get; set; }
......
public ICollection<ContactDetail> ContactDetails { get; set; }
}
public class ContactDetail
{
public Guid Id { get; set; }
public int ContactId { get; set; }
public ContactDetailTypes ContactDetailType { get; private set; }
public string Email { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
......
}
public enum ContactDetailTypes : byte
{
Email = 1,
Phone = 2,
Address = 3,
......
}
视图模型:
public class ContactViewModel
{
public int Id { get; set; }
......
public ICollection<ContactEmailViewModel> ContactEmails { get; set; }
public ICollection<ContactPhoneViewModel> ContactPhones { get; set; }
public ICollection<ContactAddressViewModel> ContactAddresses { get; set; }
}
public class ContactEmailViewModel
{
public Guid Id { get; set; }
public int ContactId { get; set; }
public string Email { get; set; }
}
public class ContactPhoneViewModel
{
public Guid Id { get; set; }
public int ContactId { get; set; }
public string Phone { get; set; }
}
public class ContactAddressViewModel
{
public Guid Id { get; set; }
public int ContactId { get; set; }
public string Address { get; set; }
}
我想将 ContactDetail 映射到 ContactEmailViewModel、ContactPhoneViewModel、ContactAddressViewModel:
CreateMap<ContactDetail, ContactEmailViewModel>()
.ForMember(dest => dest.Id, opts =>
{
opts.PreCondition(s => s.ContactDetailType == ContactDetailTypes.Email);
opts.MapFrom(src => src.Id);
})
.ForMember(dest => dest.ContactId, opts =>
{
opts.PreCondition(s => s.ContactDetailType == ContactDetailTypes.Email);
opts.MapFrom(src => src.ContactId);
})
.ForMember(dest => dest.Email, opts =>
{
opts.PreCondition(s => s.ContactDetailType == ContactDetailTypes.Email);
opts.MapFrom(src => src.Email);
});
(Phone, Address map are similar to above)
当我使用上述配置文件将 Contact 映射到 ContactViewModel 时,ContactEmails、ContactPhones、ContactAddresses 的计数始终为 0。我认为 automapper 可以检查 detailType 并将源映射到不同的目的地,但失败了。
如果我使用这三个视图模型的所有属性创建一个 ContactDetailViewModel,它会将所有属性从 ContactDetail 映射到 ContactDetailViewModel。
本例中如何使用Automapper实现一个源到多个目标的映射?
更新:
我添加了一张新地图仍然没有运气:
CreateMap<ICollection<ContactDetail>, ContactViewModel>()
.ForMember(dest => dest.ContactEmails, opts => opts.MapFrom(src => src.Where(s => s.ContactDetailType == ContactDetailTypes.Email)))
.ForMember(dest => dest.ContactPhones, opts => opts.MapFrom(src => src.Where(s => s.ContactDetailType == ContactDetailTypes.Phone)))
.ForMember(dest => dest.ContactAddresses, opts => opts.MapFrom(src => src.Where(s => s.ContactDetailType == ContactDetailTypes.Address)));
我的post为什么会投入...我问是因为我试了好几次都找不到答案...
最终实现如下:
CreateMap<Contact, ContactViewModel>()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.Id))
...
.ForMember(dest => dest.ContactEmails, opts => opts.MapFrom(src => src.ContactDetails.Where(s => s.ContactDetailType == ContactDetailTypes.Email)))
.ForMember(dest => dest.ContactPhones, opts => opts.MapFrom(src => src.ContactDetails.Where(s => s.ContactDetailType == ContactDetailTypes.Phone)))
.ForMember(dest => dest.ContactAddresses, opts => opts.MapFrom(src => src.ContactDetails.Where(s => s.ContactDetailType == ContactDetailTypes.Address)));
示例如下: 实体:
public class Contact
{
public int Id { get; set; }
......
public ICollection<ContactDetail> ContactDetails { get; set; }
}
public class ContactDetail
{
public Guid Id { get; set; }
public int ContactId { get; set; }
public ContactDetailTypes ContactDetailType { get; private set; }
public string Email { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
......
}
public enum ContactDetailTypes : byte
{
Email = 1,
Phone = 2,
Address = 3,
......
}
视图模型:
public class ContactViewModel
{
public int Id { get; set; }
......
public ICollection<ContactEmailViewModel> ContactEmails { get; set; }
public ICollection<ContactPhoneViewModel> ContactPhones { get; set; }
public ICollection<ContactAddressViewModel> ContactAddresses { get; set; }
}
public class ContactEmailViewModel
{
public Guid Id { get; set; }
public int ContactId { get; set; }
public string Email { get; set; }
}
public class ContactPhoneViewModel
{
public Guid Id { get; set; }
public int ContactId { get; set; }
public string Phone { get; set; }
}
public class ContactAddressViewModel
{
public Guid Id { get; set; }
public int ContactId { get; set; }
public string Address { get; set; }
}
我想将 ContactDetail 映射到 ContactEmailViewModel、ContactPhoneViewModel、ContactAddressViewModel:
CreateMap<ContactDetail, ContactEmailViewModel>()
.ForMember(dest => dest.Id, opts =>
{
opts.PreCondition(s => s.ContactDetailType == ContactDetailTypes.Email);
opts.MapFrom(src => src.Id);
})
.ForMember(dest => dest.ContactId, opts =>
{
opts.PreCondition(s => s.ContactDetailType == ContactDetailTypes.Email);
opts.MapFrom(src => src.ContactId);
})
.ForMember(dest => dest.Email, opts =>
{
opts.PreCondition(s => s.ContactDetailType == ContactDetailTypes.Email);
opts.MapFrom(src => src.Email);
});
(Phone, Address map are similar to above)
当我使用上述配置文件将 Contact 映射到 ContactViewModel 时,ContactEmails、ContactPhones、ContactAddresses 的计数始终为 0。我认为 automapper 可以检查 detailType 并将源映射到不同的目的地,但失败了。
如果我使用这三个视图模型的所有属性创建一个 ContactDetailViewModel,它会将所有属性从 ContactDetail 映射到 ContactDetailViewModel。
本例中如何使用Automapper实现一个源到多个目标的映射?
更新: 我添加了一张新地图仍然没有运气:
CreateMap<ICollection<ContactDetail>, ContactViewModel>()
.ForMember(dest => dest.ContactEmails, opts => opts.MapFrom(src => src.Where(s => s.ContactDetailType == ContactDetailTypes.Email)))
.ForMember(dest => dest.ContactPhones, opts => opts.MapFrom(src => src.Where(s => s.ContactDetailType == ContactDetailTypes.Phone)))
.ForMember(dest => dest.ContactAddresses, opts => opts.MapFrom(src => src.Where(s => s.ContactDetailType == ContactDetailTypes.Address)));
我的post为什么会投入...我问是因为我试了好几次都找不到答案...
最终实现如下:
CreateMap<Contact, ContactViewModel>()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.Id))
...
.ForMember(dest => dest.ContactEmails, opts => opts.MapFrom(src => src.ContactDetails.Where(s => s.ContactDetailType == ContactDetailTypes.Email)))
.ForMember(dest => dest.ContactPhones, opts => opts.MapFrom(src => src.ContactDetails.Where(s => s.ContactDetailType == ContactDetailTypes.Phone)))
.ForMember(dest => dest.ContactAddresses, opts => opts.MapFrom(src => src.ContactDetails.Where(s => s.ContactDetailType == ContactDetailTypes.Address)));