简体   繁体   English

在3层架构中自动映射多对多映射

[英]Automapper many to many mapping in 3-Tier architecture

I have two Entities model on DataAccessLayer: 我在DataAccessLayer上有两个实体模型:

Consumer 消费者

 public class Consumer 
 {
    public int Id { get; set; }
    public string Name { get; set; }
    public string PhoneNumber { get; set; }

    public virtual ICollection<Contractor> Contractors { get; set; }

    public Consumer()
    {
        Contractors = new List<Contractor>();
    }
 }

Contractor 承包商

public class Contractor 
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string PhoneNumber { get; set; }
    public string Email { get; set; }

    public virtual ICollection<Consumer> Consumers { get; set; }

    public Contractor()
    {
        Consumers = new List<Consumer>();
    }
}

...and two class on Transfer Data Layer: ...以及传输数据层上的两个类:


ConsumerTransfer 消费者转移

 public class ConsumerTransfer
 {
    public int Id { get; set; }
    public string Name { get; set; }
    public string PhoneNumber { get; set; }
    public IList<ContractorTransfer> ContractorTransfer { get; set; } 
 }

ContractorTransfer 承包商转让

 public class ContractorTransfer
 {
    public int Id { get; set; }
    public string Name { get; set; }
    public string PhoneNumber { get; set; }
    public string Email { get; set; }
 }

** **

How can I get data from Consumer to ConsumerTransfer? 我如何才能将数据从消费者传送到ConsumerTransfer?

** **

I tried to do it this way 我试图这样做

 public IEnumerable<ConsumerTransfer> GetСonsumers()
    {
        Mapper.Initialize(cfg => cfg.CreateMap<Consumer, ConsumerTransfer>()
            .ForMember(dto=>dto.Id, opt => opt.MapFrom(src => src.Id))
            .ForMember(dto => dto.Name, opt => opt.MapFrom(src => src.Name))
            .ForMember(dto => dto.PhoneNumber, opt => opt.MapFrom(src => src.PhoneNumber))
            .ForMember(dto => dto.ContractorTransfer, opt => opt.MapFrom(src => src.Contractors))
            );
        return Mapper.Map<IEnumerable<Consumer>, IEnumerable<ConsumerTransfer>>(Database.Consumers.GetAll()); 
    }

First of all, I'd rename your "ContractorTransfer" property to "Contractors". 首先,我将您的“ ContractorTransfer”属性重命名为“ Contractors”。 Generally I keep property names the same between DTOs and source types. 通常,DTO和源类型之间的属性名称相同。 Not a 100% rule, but unless I have a REALLY good reason on the client side (serialization concerns, whatever), then I don't change property names. 这不是100%的规则,但是除非我在客户端有充分的理由(关于序列化的问题,否则),否则我不会更改属性名称。

Second, your AutoMapper config is in the wrong place. 其次,您的AutoMapper配置位于错误的位置。 You need to put the Initialize in the startup of your application, not right next to your mapping. 您需要将Initialize放在应用程序的启动中,而不是放在映射旁边。

Third, your configuration is way too verbose. 第三,您的配置过于冗长。 AutoMapper automatically maps properties with the same name. AutoMapper会自动映射具有相同名称的属性。

Fourth, you're missing a map for the second set of source/destination types. 第四,您缺少第二套源/目标类型的地图。 Assuming you've fixed your inconsistent property name, here's your config: 假设您已修复属性名称不一致的问题,则配置如下:

Mapper.Initialize(cfg => {
    cfg.CreateMap<Consumer, ConsumerTransfer>();
    cfg.CreateMap<Contract, ContractTransfer>();
});

Then later on when you execute the map: 然后,当您执行地图时:

Mapper.Map<Consumer, ConsumerTransfer>(consumer);

That's it. 而已。

public IEnumerable<ConsumerTransfer> GetСonsumers()
{
    Mapper.Initialize(cfg =>
    {
        cfg.CreateMap<Consumer, ConsumerTransfer>()
            .ForMember(dto => dto.Id, opt => opt.MapFrom(src => src.Id))
            .ForMember(dto => dto.Name, opt => opt.MapFrom(src => src.Name))
            .ForMember(dto => dto.PhoneNumber, opt => opt.MapFrom(src => src.PhoneNumber))
            .ForMember(dto => dto.ContractorTransfer, opt => opt.MapFrom(src => src.Contractors));

        cfg.CreateMap<Contractor, ContractorTransfer>();
    });

    return Mapper.Map<IEnumerable<ConsumerTransfer>>(Database.Consumers.GetAll());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM