使用AutoMapper通过匹配ID映射到列表中的元素

Using AutoMapper to map to elements in list by matching ID

理想情况下,我希望使用 AutoMapper 将更新应用到包含多个复杂类型列表的复杂类型。我知道这很容易完成,因为 AutoMapper 将处理基本类型内属性的映射。

但是,因为我要更新它(基于 PUT 请求),所以每个对象都有一个 ID。那么,理想情况下,这意味着我不仅要创建新对象,还要映射到现有对象及其属性。现在,对于 root,这很容易,因为我的映射如下所示:

CreateMap<MyObj,MyObj>
  .ForMember(dest => dest.Id, opt => opt.Ignore());
CreateMap<MyOtherObj, MyOtherObj>
  .ForMember(dest => dest.Id, opt => opt.Ignore());

但是,假设 MyObj 如下所示:

public class MyObj
{
  public int Id {get;set;}
  public List<MyOtherObj> Objs {get;set;}
}

MyOtherObj 看起来像:

public class MyOtherObj 
{
  public int Id {get;set;}
  public string Name {get;set;}
}

我从以下内容开始:

var originalObj = new MyObj 
{
  Id = 1,
  Objs = new List<MyOtherObj> 
  {
    new MyOtherObj 
    {
      Id = 1,
      Name = "Apple"
    },
    new MyOtherObj
    {
      Id = 2,
      Name = "Banana"
    }
  }
};

然后我在 PUT 请求中收到以下内容:

var updateObj = new MyObj 
{
  Id = 1,
  Objs = new List<MyOtherObj> 
  {
    new MyOtherObj 
    {
      Id = 2,
      Name = "Cherry"
    },
    new MyOtherObj
    {
      Id = 1,
      Name = "Date"
    }
  }
};

我希望能够做类似的事情:

var mappedObj = _mapper.Map(updateObj, originalObj);

但问题是我无法弄清楚如何通知 AutoMapper 有关标识符的信息,因此不是通过 Objs 盲目映射,它实际上按 ID 匹配列表(在原始和更新之间)版本),然后应用映射。

问题:

  1. 这样的事情可能吗?
  2. 如果是这样,是否可以使用 .When() 方法或类似方法进一步采取措施,以便我可以 a) 为匹配的 ID 映射更新,b) 创建新对象,其中我的更新包含不在原始中的 ID,以及 c ) 从原始对象中删除那些不在更新中的对象(同样,通过 ID,因此我不必手动处理我的基础对象中的每个属性)?

谢谢!

根据@Lucian Bargaoanu 的提示,使用 AutoMapper.Collection 库和以下内容是可能的:

CreateMap<MyObj, MyObj>()
  .ForMember(dest => dest.Id, opt => opt.Ignore())
  .EqualityComparison((dto, entity) => dto.Id == entity.Id); //Updated this line