【问题标题】:Automapper many to many mapping in 3-Tier architectureAutomapper 三层架构中的多对多映射
【发布时间】:2016-09-26 14:24:13
【问题描述】:

我在 DataAccessLayer 上有两个实体模型:

消费者

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

承包商

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

...以及传输数据层上的两个类:


消费者转移

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

承包商转让

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

**

如何从 Consumer 获取数据到 ConsumerTransfer?

**

我试着这样做

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

【问题讨论】:

    标签: c# asp.net asp.net-mvc entity-framework automapper


    【解决方案1】:

    首先,我将您的“ContractorTransfer”属性重命名为“Contractors”。通常,我在 DTO 和源类型之间保持属性名称相同。不是 100% 的规则,但除非我在客户端有一个非常好的理由(序列化问题等),否则我不会更改属性名称。

    其次,您的 AutoMapper 配置放错了位置。您需要将 Initialize 放在应用程序的启动中,而不是紧邻映射。

    第三,你的配置太冗长了。 AutoMapper 自动映射同名的属性。

    第四,您缺少第二组源/目标类型的映射。假设您已修复不一致的属性名称,这是您的配置:

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

    然后在您执行地图时:

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

    就是这样。

    【讨论】:

    • cfg.CreateMap().ReverseMap();而不是写两行代码。
    【解决方案2】:
    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());
    }
    

    【讨论】:

      猜你喜欢
      • 2020-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-19
      • 1970-01-01
      • 2021-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多