AutoMapper 避免嵌套循环

AutoMapper avoid nested loops

我目前正在使用 Automapper 将我的域模型映射到 DTO。在我的里面 域模型我有 3 个布尔属性(IsHomeownerIsTenantIsLivingWithParents),用于设置 属性 的值 在 ViewModel 中,即 PersonDTO 称为 LivingStatus

但是,为了得到我的最终结果,我必须循环遍历 Person 模型,创建字典 存储我的值,然后使用 AfterMap 创建一个嵌套循环并在其中设置值。

虽然有效但不是理想的解决方案,因为随着数据的增加,它更有可能造成内存泄漏 尺寸。

所以想知道 AutoMapper 中是否有任何东西可以避免这种情况?

这是我的代码

查看模型

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

领域模型

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

您可以避免所有这些并以一种方式扩展您的 PersonDto,然后按应有的方式映射值,或者您可以为此目的编写自己的解析器 也许将逻辑放在 setter.

中并不是最好的方法
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; }
  }

如果您更喜欢使用 Resolver 解决方案,请告诉我。我会尽力帮助你。

终于找到了一个更好的解决方案,方法是创建一个 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;
}

映射配置

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