简体   繁体   English

Entity Framework Core 更新子实体问题

[英]Entity Framework Core Update child entities problem

In my ASP.NET Core 2.2.在我的 ASP.NET Core 2.2 中。 MVC project I have a master-detail form that I use for editing a PARENT table that also has a list of child entities (stored in CHILD table). MVC 项目我有一个主从表单,用于编辑一个 PARENT 表,该表也有一个子实体列表(存储在 CHILD 表中)。

When I save the modifications on the form I first save the changes to the parent entity and then run the following method to update the corresponding child entities:当我在表单上保存修改时,我首先将更改保存到父实体,然后运行以下方法来更新相应的子实体:

private void UpdateChildList(ParentModel model)
{
    // lists
    var listOld = _parents.Get(model.IdParent).ListChilds;
    var listNew = model.ListChilds;
    var listNewInt = from x in listNew select x.IdChild;

    // 1. remove deleted
    var deleteList = new List<int>();
    deleteList = listOld.Where(t => !listNewInt.Contains(t.IdChild)).Select(x => x.IdChild).ToList();

    foreach (var d in deleteList)
    {
        var item = listOld.Where(x => x.IdChild == l).First();
        _parents.DeleteChild(item);
    }

    // 2. update existing
    var list = from x in listNew
    where x.IdChild > 0
    select x;

    foreach (var item in list)
    {
        _parents.UpdateChild(item);
    }

    // 3. add new 
    list = from x in listNew
    where x.IdChild == 0
    select x;

    foreach (var item in list)
    {
        _parents.AddChild(item);
    }
}

1. deleting works OK & 3. adding works OK, but 2. UPDATING produces the following error: 1.删除作品 OK & 3.添加作品 OK,但是2. UPDATING 产生以下错误:

InvalidOperationException: The instance of entity type 'Child' cannot be tracked because another instance with the same key value for {'IdChild'} is already being tracked. InvalidOperationException:无法跟踪实体类型“Child”的实例,因为已经在跟踪具有相同键值 {'IdChild'} 的另一个实例。 When attaching existing entities, ensure that only one entity instance with a given key value is attached.附加现有实体时,请确保仅附加一个具有给定键值的实体实例。 Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.考虑使用“DbContextOptionsBuilder.EnableSensitiveDataLogging”来查看冲突的键值。

Note: I'm using service.AddScoped to add services in my Startup class.注意:我正在使用service.AddScoped在我的 Startup class 中添加服务。

EDIT: I'm adding the code from my HTTPPost (in controller):编辑:我正在从我的 HTTPPost(在控制器中)添加代码:

[HttpPost]
public IActionResult Edit(ParentModel model)
{
    // valid check
    if (!ModelState.IsValid)
    {
        /// ... some lists for dropdowns here

        return View(model);
    }

    var item = _parents.Get(model.IdParent);

    item.Field1 = model.Field1;
    // ... and other fields

    // update parent
    _parents.Update(item);

    // update Child list
    UpdateChildList(model);

    return RedirectToAction("Index");

}

EDIT2: adding my code for delete/update/add child records EDIT2:添加我的删除/更新/添加子记录的代码

public void AddChild(Child item)
{
    _dbContext.Add(item);
    _dbContext.SaveChanges();
}

public void UpdateChild(Child item)
{
    _dbContext.Update(item);
    _dbContext.SaveChanges();
}

public void DeleteChild(Child item)
{
   _dbContext.Remove(item);
   _dbContext.SaveChanges();
}

When you do:当你这样做时:

var listOld = _parents.Get(model.IdParent).ListChilds;

Entity Framework retrieves information from the context and begin tracking this entities and when you do:实体框架从上下文中检索信息并开始跟踪这些实体,当您这样做时:

_parents.UpdateChild(item);

you invoke:你调用:

_dbContext.Update(item);

Which on other side tries to attaches this entity to a context again and sets its EntityState to Modified and so you get an exception.在另一边尝试再次将此实体附加到上下文并将其EntityState设置为已Modified ,因此您会遇到异常。

When you retrieve information from the database and then work with it, you are in the so called "Connected scenario" and Entity Framework context track all retrieved entities.当您从数据库中检索信息然后使用它时,您处于所谓的“连接场景”中,并且实体框架上下文跟踪所有检索到的实体。 As soon as you modify some data of this entities, the context sets its EntityState to Modified because of modification is performed.一旦您修改了此实体的某些数据,上下文就会将其EntityState设置为Modified ,因为执行了修改。 So, then you can call the SaveChanges() method, it builds and executes Update statement in the database.因此,您可以调用SaveChanges()方法,它在数据库中构建并执行 Update 语句。

So you have two options:所以你有两个选择:

  1. Add .AsNoTracking() in your retrieval query so you will do a no tracking queries and no entities will be added to the db context respectively.在您的检索查询中添加.AsNoTracking()以便您将执行无跟踪查询,并且不会将实体分别添加到数据库上下文中。 Then you will work in "Disconnected scenario" and you can use db context Update() method;然后您将在“断开连接的场景”中工作,您可以使用 db context Update()方法;

  2. Change the UpdateChild method by mapping field by field so changing a field in the entity will set it's EntityState to Modified .通过逐个字段映射来更改UpdateChild方法,因此更改实体中的字段会将其EntityState设置为Modified Then remove _dbContext.Update(item) at all because SaveChanges() will do the entire work.然后完全删除_dbContext.Update(item)因为SaveChanges()将完成整个工作。

Another thing to mention - doing a SaveChanges() in a loop is generally not a good idea.另一件要提的事情 - 在循环中执行SaveChanges()通常不是一个好主意。 This mean that you send (n) queries to database, where (n) is the number of the records.这意味着您向数据库发送 (n) 个查询,其中 (n) 是记录数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Entity Framework Core 中更新父实体时添加或更新子实体 - Add or Update child entities when updating a parent entity in Entity Framework Core Entity Framework Core 在更新期间删除实体 - Entity Framework Core deletes entities during update 如何在 Entity Framework Core 中的父更新时从父集合中删除子实体? - How to remove child entities from parent collection on parent update in Entity Framework Core? 使用带有现有子实体的实体框架在数据库中创建实体时出现问题 - Problem creating an entity in the database using Entity Framework with existing child entities 与Entity Framework Core 2.0的多个子实体中的属性名称相同 - Same property name in several child entities with Entity Framework Core 2.0 .NET 核心实体框架 - 只添加新的子实体 - .NET Core Entity Framework - Only add new child entities 完整插入/更新/删除实体框架中的子实体 - Complete Insert/Update/Delete of Child Entities in Entity Framework 实体框架核心2.1用于更新具有关系的实体 - Entity Framework Core 2.1 failling to update entities with relations 实体框架:删除子实体 - Entity Framework : deleting child entities 在Entity Framework中加载子实体 - Load child entities in Entity Framework
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM