Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 来自WebApi的EF6合并实体_C#_Entity Framework_Crud_Entity Framework 6.1 - Fatal编程技术网

C# 来自WebApi的EF6合并实体

C# 来自WebApi的EF6合并实体,c#,entity-framework,crud,entity-framework-6.1,C#,Entity Framework,Crud,Entity Framework 6.1,我一直肩负着使积垢系统现代化的光荣使命(讽刺)。我正在使用EF6.1.1和WebApi。我使用DTO发送实体(目前的动态对象将在一切正常时创建静态类型,还将进行调用async) 然后,我更新Person对象上的字段,或者使用Knockout和ko.mapping添加/删除/更新PersonNames集合 我将结果发布到这个WebApi方法 [HttpPost] public void Post([FromBody]Person person) { personRepository.Mer

我一直肩负着使积垢系统现代化的光荣使命(讽刺)。我正在使用EF6.1.1和WebApi。我使用DTO发送实体(目前的动态对象将在一切正常时创建静态类型,还将进行调用
async

然后,我更新
Person
对象上的字段,或者使用
Knockout
ko.mapping添加/删除/更新
PersonNames
集合

我将结果发布到这个WebApi方法

[HttpPost]
public void Post([FromBody]Person person)
{
    personRepository.Merge(person);
}
personRepository.Merge
中,所有id等都是正确的

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();
}

考虑到你提到的这是一个积垢系统,我觉得这一切都是合理的。我看不出您如何才能真正避免从DTO映射回域实体(例如Person)

我想您已经考虑过了,但是使用AutoMapper之类的工具删除尽可能多的锅炉板合并代码怎么样


导航属性的映射确实会变得复杂(即DTO的对象图与实体的对象图之间的映射)。这个链接比我能看到的要详细得多:

奇怪的是,它还没有被包括在内,大多数系统都是令人遗憾的CRUD SystemsHanks,我知道automapper,它可以用于Entity>DTO,但另一方面非常危险。也看了Breeze,但我不喜欢它的RIA方法(查询是在客户端执行的).是的-完全同意。缺乏对断开连接的实体图的实体框架支持(例如,与NHibernate相比)。我通常只是将服务分割成对图形的特定部分进行操作的命令。显然,对于需要完整CRUD端点的现有应用程序,您没有任何用处。祝你好运以防万一,您没有偶然发现它-它可能值得一看GraphDiff()。我听说它提到了一个相当数量的,所以,但从来没有实际使用它。稍后可能会玩一玩GraphDiff+AutoMapper+EF,看看效果如何。我有预算,所以我必须在项目之外检查一下,但谢谢。现在,我将手动执行。是的,我自己主要使用CQR,但正如你指出的,我被CRUD卡住了。
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();
}