The instance of entity type 'Book' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. 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.
上面這個錯誤把我折磨透了,沒辦法只能把Update的方法仔細研究了一遍。
原因:
DbContext 實例會自動跟蹤從數據庫返回的實體。 調用 SaveChanges 時,系統將檢測對這些實體所做的更改並根據需要更新數據庫。有時會使用一個上下文實例查詢實體,然后使用實例對其進行保存,或者使用其他實例對實體進行保存。兩種情況的做法不一樣,需要區別對待。
情況一:共用一個DbContex對實體查詢與保存
由於DbContex已經存在一個實體,只需要更新實體數據就可以。如果不存在就插入。
public static void InsertOrUpdate(BloggingContext context, Blog blog) { var existingBlog = context.Blogs.Find(blog.BlogId); if (existingBlog == null) { context.Add(blog); } else { context.Entry(existingBlog).CurrentValues.SetValues(blog); } context.SaveChanges(); }
情況二:不同DbContext對實體進行查詢與保存
由於DbContex不存在實體,這個實體是否在數據庫中存在我們需要判斷才行。
常見 Web 應用程序,屬於這種情況。實體被查詢、發送到客戶端、被修改、在請求中發送回服務器,然后進行保存。
public static void InsertOrUpdate(DbContext context, object entity) { context.Update(entity); context.SaveChanges(); }
EF Core 2.0之后,Update 方法通常將實體標記為更新。 但是,如果實體具有自動生成的鍵且未設置任何鍵值,則實體會自動標記為插入。