云中客

梦想有多大,就能走多远

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  118 随笔 :: 4 文章 :: 169 评论 :: 0 引用

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 方法通常将实体标记为更新。 但是,如果实体具有自动生成的键且未设置任何键值,则实体会自动标记为插入。

 

posted on 2019-10-13 21:30  走遍江湖  阅读(333)  评论(0编辑  收藏