Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.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# 实体框架核心更新子实体问题_C#_Asp.net Core_Entity Framework Core - Fatal编程技术网

C# 实体框架核心更新子实体问题

C# 实体框架核心更新子实体问题,c#,asp.net-core,entity-framework-core,C#,Asp.net Core,Entity Framework Core,在我的ASP.NET Core 2.2中。MVC项目我有一个主详细信息表单,用于编辑父表,该父表还包含子实体列表(存储在子表中) 在表单上保存修改时,我首先将更改保存到父实体,然后运行以下方法更新相应的子实体: private void UpdateChildList(父模型) { //列表 var listOld=_parents.Get(model.IdParent.ListChilds); var listNew=model.ListChilds; var listNewInt=从list

在我的ASP.NET Core 2.2中。MVC项目我有一个主详细信息表单,用于编辑父表,该父表还包含子实体列表(存储在子表中)

在表单上保存修改时,我首先将更改保存到父实体,然后运行以下方法更新相应的子实体:

private void UpdateChildList(父模型)
{
//列表
var listOld=_parents.Get(model.IdParent.ListChilds);
var listNew=model.ListChilds;
var listNewInt=从listNew中的x选择x.IdChild;
//1.删除
var deleteList=新列表();
deleteList=listOld.Where(t=>!listNewInt.Contains(t.IdChild)).Select(x=>x.IdChild.ToList();
foreach(deleteList中的变量d)
{
var item=listOld.Where(x=>x.IdChild==l).First();
_父母、子女(项目);
}
//2.更新现有的
var list=从listNew中的x开始
其中x.IdChild>0
选择x;
foreach(列表中的变量项)
{
_parents.UpdateChild(项目);
}
//3.添加新的
列表=从listNew中的x开始
其中x.IdChild==0
选择x;
foreach(列表中的变量项)
{
_父母。添加子女(项目);
}
}
1。删除作品正常&3。添加作品正常,但2。更新会产生以下错误:

InvalidOperationException:无法跟踪实体类型“Child”的实例,因为已在跟踪另一个具有{IdChild}相同键值的实例。附着现有实体时,请确保仅附着一个具有给定键值的实体实例。考虑使用“dBraveTopStudioBuffel.EnabelSythViDeAtCug”来查看冲突的键值。

注意:我正在使用
service.AddScoped
在我的启动类中添加服务

编辑:我正在从我的HTTPPost(在控制器中)添加代码:

[HttpPost]
公共IActionResult编辑(父模型)
{
//有效支票
如果(!ModelState.IsValid)
{
///…这里有一些下拉列表
返回视图(模型);
}
var item=_parents.Get(model.IdParent);
item.Field1=model.Field1;
//…和其他领域
//更新父项
_更新(项目);
//更新子列表
更新文档列表(模型);
返回操作(“索引”);
}
EDIT2:为删除/更新/添加子记录添加我的代码

public void AddChild(子项)
{
_dbContext.Add(item);
_dbContext.SaveChanges();
}
public void UpdateChild(子项)
{
_dbContext.Update(项目);
_dbContext.SaveChanges();
}
公共无效删除子项(子项)
{
_dbContext.Remove(项);
_dbContext.SaveChanges();
}
当您执行以下操作时:

var listOld = _parents.Get(model.IdParent).ListChilds;
实体框架从上下文中检索信息并开始跟踪此实体,当您执行以下操作时:

_parents.UpdateChild(item);
您调用:

_dbContext.Update(item);
在另一端,它尝试再次将该实体附加到上下文,并将其
EntityState
设置为
Modified
,因此您会得到一个异常

当您从数据库检索信息并使用它时,您处于所谓的“连接场景”中,实体框架上下文跟踪所有检索到的实体。一旦您修改了此实体的某些数据,由于执行了修改,上下文将其
EntityState
设置为
Modified
。因此,您可以调用
SaveChanges()
方法,它在数据库中构建并执行Update语句

所以你有两个选择:

  • 在检索查询中添加
    .AsNoTracking()
    ,这样您将执行无跟踪查询,并且不会将任何实体分别添加到数据库上下文中。然后您将在“断开连接的场景”中工作,您可以使用db上下文
    Update()
    方法

  • 通过逐字段映射来更改
    UpdateChild
    方法,以便更改实体中的字段将其
    EntityState
    设置为
    Modified
    。然后删除
    \u dbContext.Update(item)
    ,因为
    SaveChanges()
    将完成全部工作


  • 另一件需要提及的事情是,在循环中执行
    SaveChanges()
    通常不是一个好主意。这意味着您向数据库发送(n)个查询,其中(n)是记录数。

    错误准确地告诉您发生了什么。您正在尝试附加已附加到第一行的项目。虽然这只是一个假设,因为您没有显示在所有这些
    \u parentDbContext
    方法中发生了什么。我添加了一些额外的代码以使我的情况更加清楚。我不确定我附加已附加的项目的问题在哪里-更新操作是“附加”吗?可能是因为我在同一接口/存储库中有父级和子级CRUD操作?请提供所有相关代码
    DeleteChild()
    UpdateChild()
    AddChild()
    不是实体框架方法。更新项的逻辑是什么?你为什么打电话给
    1。删除已删除的
    //2。更新现有的
    和//3。是否为同一列表添加新的?为了更新,您可以考虑尝试AutoPAPER将VIEWMET映射到实体并更新该项。@ Erik Philips:我把相关代码添加到我的PASSY谢谢中。我将AsNoTracking()添加到“Get”父实体中,更新工作正常*循环遍历记录并进行保存是因为我在搜索解决方案,因为我无法将更新获取到workEDIT:解决方案不太有效。它可以更新子列表中已更改的项目,也可以在子列表中添加新项目,但不会从子列表中删除已删除的项目。我仍然需要手动检查已删除的项目(如上面的代码)并在循环中删除吗?会出现什么错误?我将在RemoveRange()方法中传递我的列表。但是如果你坚持在l中删除()并不是什么大问题