在我的ASP.NET核心,我们使用EF核心。当保存具有子记录列表的记录时,我们会得到以下错误:
无法跟踪实体类型Child的实例,因为另一个具有{'Id'}键值相同的实例已经被跟踪。
一步步地:
中
简化代码如下:
// Get the record from the database
var record = _dbContext.Parents
.Include(x => p.SomeOtherObject)
.Include(x => x.ListChildren)
.FirstOrDefault(x => x.IdParent == id);
// then we do some changes to Parent and ListChildren
// we do not do any changes to SomeOtherObject!!!
// save changes
_dbContext.Update(record);
_dbContext.SaveChanges();
// definition of entities
public class Parent
{
public int IdParent { get; set; }
public string Name {get; set;}
public string Surname {get; set;}
public int IdSomeOtherObject { get; set; }
[ForeignKey("IdSomeOtherObject")]
public virtual SomeOtherObject SomeOtherObject { get; set; }
public virtual List<Child> ListChildren { get; set; }
}
public class Child
{
public int IdChild { get; set; }
public int IdParent { get; set;}
public string Name { get; set; }
}
public class SomeOtherObject
{
public int IdSomeOtherObject { get; set; }
public string PropertiesBlahBla { get; set; }
}现在,我知道我们可以将.AsNoTracking()添加到Get操作中,但问题是,当保存Parent时,EntityFramework将执行和UPDATE SQL语句,甚至对于SomeOtherObject (没有以任何方式更改),这对于我们的数据/输入场景来说是不可接受的。
还有其他方法来传递这个错误吗?
发布于 2020-05-25 17:16:55
尝试删除_dbContext.Update(record);。您的实体应该已经被跟踪,所以应该保存更改。
如Update docs所述:
默认情况下,
使用修改后的状态开始跟踪可从给定实体访问的给定实体和条目。
因此,在这种情况下,它似乎是不必要的。
UPD
在chat的讨论中,发现子跟踪集合被替换如下:
record.ListChildren = someModel.ListChildren.Where(...).ToList()这导致添加了具有已跟踪ids的元素。因此,ListChildren应该通过保存已经跟踪的项目来更新,比如推荐的here。
https://stackoverflow.com/questions/62006837
复制相似问题