4

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.

kennho
  • 211
  • 5
  • 12
  • We can only give opinions here. It depends much on your own preferences and non-functional requirements. See also: https://stackoverflow.com/a/30824229/861716. – Gert Arnold Sep 27 '20 at 21:20

1 Answers1

3

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();
Steve Py
  • 26,149
  • 3
  • 25
  • 43