简体   繁体   English

AutoMapper避免嵌套循环

[英]AutoMapper avoid nested loops

I am currently using Automapper to map from my domain model to DTO. 我目前正在使用Automapper将域模型映射到DTO。 Inside my Domain model I have 3 bool properties ( IsHomeowner , IsTenant , IsLivingWithParents ) which are used to set the value of a property inside the ViewModel ie PersonDTO called LivingStatus 在我的Domain模型中,我有3个bool属性( IsHomeownerIsTenantIsLivingWithParents ),这些属性用于设置ViewModel内部的属性值,即PersonDTO称为LivingStatus

However, to get to my end result I am having to loop through the Person model, create Dictionary to store my values and then using AfterMap create a nested loop and set the value inside there. 但是,要获得最终结果,我必须遍历Person模型,创建Dictionary以存储我的值,然后使用AfterMap创建一个嵌套循环并在其中设置值。

Although it works but is not an ideal solution because it is more likely to create memory leaks as data increases in Size. 尽管它可以工作,但不是理想的解决方案,因为随着数据大小的增加,它更有可能造成内存泄漏。

So was wondering if there is anything in AutoMapper to avoid this? 所以想知道AutoMapper中是否有什么可以避免这种情况?

Here is my code 这是我的代码

View Model 查看模型

public class PersonDTO{
  public int Id { get; set; }
  public string FirstName { get; set; }
  public string Surname { get; set; }
  public Status LivingStatus { get; set; }
}

Domain Model 领域模型

public class Person{
   public int Id { get; set; }
   public string FirstName { get; set; }
   public string Surname { get; set; }
   public bool IsHomeOwner { get; set; }
   public bool IsTenant { get; set; }
   public bool IsLivingWithParents { get; set; }
}

public enum Status{
   Homeowner=1,
   Tenant=2,
   LivingWithParents=3
}
public List<PersonDTO> GetEmployee(List<Person> persons)
{
   var livingStatus = new Dictionary<int, Status>();
   foreach (var person in persons)
   {
       if (person.IsHomeOwner)
       {
          livingStatus.Add(person.Id, Status.Homeowner);
       }
       else if (person.IsTenant)
       {
          livingStatus.Add(person.Id, Status.Tenant);
       }
       else
       {
          livingStatus.Add(person.Id, Status.LivingWithParents);
       }
   }

   return _mapper.Map<List<Person>, List<PersonDTO>>(persons, opts => opts.AfterMap((src, dest) { 
   foreach(var person in dest)
   {
     person.LivingStatus = livingStatus.Single(x => x.Key == person.Id).Value;
   }
   }));
}

Finally found a better solution by creating a Method which handles the conversion and then using it in the mapping configuration :) 最后找到一个更好的解决方案, Method是创建一个Method来处理转换,然后在映射配置中使用它:)

private Status TypeConverter(Person person)
{
    if (person.IsHomeOwner)
    {
      return Status.Homeowner;
    }
    else if (person.IsTenant)
    {
      return Status.Tenant;
    }
    else
    {
      return Status.LivingWithParents;
    }

    return person.Status;
}

Mapping configuration 映射配置

CreateMap<Person, PersonDTO>()
                .ForMember(dest => dest.LivingStatus, opt => opt.MapFrom(src => TypeConverter(src)));

You can avoid all that and extend your PersonDto in a way that then the values are mapped as they should be or you can write your own Resolver for the purpose Maybe it is not a best way to put a logic in a setter. 您可以避免所有这些并以某种方式扩展您的PersonDto,然后按原样映射值,或者可以出于此目的编写自己的解析器,也许这不是将逻辑放入设置器中的最佳方法。

public class PersonDto
  {
    private Status status;
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string Surname { get; set; }

    public Status LivingStatus
    {
      get => status;

      set
      {
        status = value;

        switch (status)
        {
          case Status.Homeowner:
            IsHomeOwner = true;
            IsTenant = false;
            IsLivingWithParents = false;
            break;

          case Status.LivingWithParents:
            IsHomeOwner = false;
            IsTenant = false;
            IsLivingWithParents = true;
            break;

          case Status.Tenant:
            IsHomeOwner = false;
            IsTenant = true;
            IsLivingWithParents = false;
            break;

          default:
            throw new ArgumentOutOfRangeException();
        }
      }
    }


    public bool IsHomeOwner { get; set; }
    public bool IsTenant { get; set; }
    public bool IsLivingWithParents { get; set; }
  }

Let me know if you prefer solution with the Resolver. 让我知道您是否喜欢使用解析器的解决方案。 I will try to help you. 我会尽力帮助您。

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

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