来自 WebApi 的 EF6 合并实体
-
20-12-2019 - |
题
我肩负着使 CRUD 系统现代化的光荣使命(讽刺)。我正在使用 EF 6.1.1 和 WebApi。我使用 DTO 发送实体(目前动态对象将在一切正常工作时创建静态类型,还将进行调用 async
)
[HttpGet]
public dynamic Get(int id)
{
var p = personRepository.Get(id);
return new
{
p.PersonId,
p.BirthYear,
p.DeathYear,
p.Comment,
PersonNames = p.PersonNames.Select(pn => new { pn.PersonId, pn.PersonNameId, pn.NameTypeId, pn.Firstname, pn.Prefix, pn.Surname })
};
}
然后我更新字段 Person
对象或添加/删除/更新 PersonNames
收集使用 Knockout
和 ko.mapping
我将结果发布到此 WebApi 方法
[HttpPost]
public void Post([FromBody]Person person)
{
personRepository.Merge(person);
}
所有 id 等都是正确的,在 personRepository.Merge
我试过了
public void Merge(Person person)
{
db.People.AddOrUpdate(person);
db.SaveChanges();
}
这适用于直接在 personobject 上的字段,但不适用于在 PersonNames
我可以在不编写手动合并代码的情况下支持这一点吗?
解决方案最终做了这个
public void Merge(Person person)
{
db.People.AddOrUpdate(person);
var existingNames = db.PersonNames.Where(pn => pn.PersonId == person.PersonId).ToList();
var deleted = existingNames.Where(pn => person.PersonNames.All(d => d.PersonNameId != pn.PersonNameId));
db.PersonNames.RemoveRange(deleted);
foreach (var name in person.PersonNames)
{
db.PersonNames.AddOrUpdate(name);
}
db.SaveChanges();
}
解决方案
鉴于您提到这是一个 CRUD 系统,这对我来说看起来很合理。我不明白如何才能真正避免从 DTO 映射回域实体(例如人)
我希望您已经想到了这一点,但是如何使用 AutoMapper 之类的工具删除尽可能多的样板合并代码呢? https://github.com/AutoMapper/AutoMapper
导航属性的映射确实变得复杂(即DTO 的对象图与实体的对象图之间的映射)。这个链接比我能提供的更详细: http://rogeralsing.com/2013/12/01/why-mapping-dtos-to-entities-using-automapper-and-entityframework-is-horrible/
不隶属于 StackOverflow