使用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 匹配列表(在原始和更新之间)版本),然后应用映射。
问题:
- 这样的事情可能吗?
- 如果是这样,是否可以使用 .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
理想情况下,我希望使用 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 匹配列表(在原始和更新之间)版本),然后应用映射。
问题:
- 这样的事情可能吗?
- 如果是这样,是否可以使用 .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