我肩负着使 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 收集使用 Knockoutko.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/

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top