EF Core - DbContext.Update vs DbContext.Entry(exitingEntity).CurrentValues.SetValues(entity);

2.3k Views Asked by At

According to microsoft docs on disconnected entities, if the entity is not using auto-generated keys, then the application must decide whether the entity should be inserted or updated:

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

Suppose I use this in the else block (instead of the one shown above):

    else
    {
        context.Update(blog);
    } 

Is it advisable? How is .Update different from .Entry(existingBlog).CurrentValues.SetValues(blog) especially in terms of the complexity? Which will be less costly to call? I can't seem to find information on how the 2 methods are implemented and their complexity.

1

There are 1 best solutions below

0
On

context.Update will attempt to begin tracking the entity. Since you used Find, the DbContext is already tracking an entity so calling Update with the detached entity reference would result in an exception that an entity with that ID is already tracked.

Update can be used if you know the record both does exist, and that the DbContext is not tracking it.

The alternative to satisfy the tracking check without a DB load would be something like this:

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