【发布时间】:2020-06-19 07:22:00
【问题描述】:
理想情况下,我希望使用 AutoMapper 将更新应用于包含其自己的多个复杂类型列表的复杂类型。我知道这很简单,因为 AutoMapper 将处理基类型中属性的映射。
但是,因为我要更新它(基于 PUT 请求),所以每个对象都有一个 ID。理想情况下,这意味着我不只是创建新对象,而是映射到现有对象及其属性。现在,对于根来说,这很容易,因为我的映射如下所示:
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 中的 ID,以及 c) 删除那些不在更新中的原始对象(同样,按 ID,因此我不必手动处理基础对象中的每个属性)?
谢谢!
【问题讨论】:
-
研究 AutoMapper.Collection.
-
警告,咆哮接踵而至.... 让 automapper 做到这一点,即使你可以,似乎是适合这项工作的错误工具。在最好的日子里,你会在一个已经有太多抽象的地方抽象出逻辑。它不直观,并且它使用具有不可预测副作用的自动映射器
-
我很欣赏这一点,但在我的情况下,我的 DTO 仅以大约 1:1 的比例映射到 EF 对象,因此 AutoMapper 可以节省转换时间,反之亦然。尤其是因为我已经从 EF 对象中获取了所有多对多对象,因此手动将它们全部映射出来以进行更新是一件非常痛苦的事情。
-
根据您的第二个问题-您为什么不使用从 PUT 请求中获得的对象列表?在我看来,您实际上不需要任何映射,因为您基本上是用您获得的列表替换整个列表。
标签: c# automapper