EF核心-DbContext.Update与DbContext.EntryexitingEntity.CurrentValues.SetValuesentity;

问题描述

根据disconnected entities上的Microsoft文档,如果实体未使用自动生成的密钥,则应用程序必须确定是否应插入或更新实体:

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();
}

假设我在else块中使用了它(而不是上面显示的那个):

    else
    {
        context.Update(blog);
    } 

建议吗? .Update.Entry(existingBlog).CurrentValues.SetValues(blog)有何不同,尤其是在复杂性方面?哪个通话费用更低?我似乎找不到有关这两种方法的实现方式及其复杂性的信息。

解决方法

context.Update将尝试开始跟踪实体。由于您使用了Find,因此DbContext已经在跟踪实体,因此使用分离的实体引用调用Update会导致一个例外,即已经跟踪了具有该ID的实体。

如果您知道记录确实存在,并且DbContext是对其进行跟踪,则可以使用

Update

在没有DB负载的情况下满足跟踪检查的替代方法如下:

if (blog.BlogId == 0)  // New row,Identity ID set by DB.
    context.Blogs.Add(blog);
else
{
    var existingBlog = context.Blogs.Local.SingleOrDefault(blog.BlogId);
    if (existingBlog == null)
        context.Update(blog); // Not tracked,so call Update to update and track
    else
        context.Entry(existingBlog).CurrentValues.SetValues(blog); // Tracked,so copy across values.
}
context.SaveChanges();