What is the simplest way to implement Entity Framework 6 Add-or-Update method

I have a project that uses Entity Framework 6 that adds or updates (i.e. Upsert) for a group of different entity types. For each of these entities, there is a surrogate integer identifier (i.e., Primary key), a natural key (e.g., customer ID) used for external lookups, and a set of descriptive fields (such as name, description, etc.).

I have an AddOrUpdate method that searches for a natural key, finds an existing object in the database and updates the object with new values ​​(if it exists), or creates a new object and adds it to the database (if it doesn't already exist).

Here's an example of a method I came up with (note that "key" is a natural key, not a surrogate identifier):

public void AddOrUpdate(int key, string name)
{
    var customer = _database.Customers
        .FirstOrDefault(p => p.Key == key);

    var exists = customer != null;

    if (!exists)
        customer = new Customer();

    customer.Name = name;
    // Update other descriptive fields here

    if (!exists)
        _database.Customers.Add(customer);

    _database.Save();
}

      

The code works correctly, but it always feels a little messy. I'm curious to see if anyone has a better way to solve this problem with Entity Framework that is structurally simpler, reads better, or can be done in fewer lines of code (without compromising readability) and still unit test easily.

If so, please post your refactoring of the above code so I can learn from your example.

+3


source to share


1 answer


EntityFramework already implements this for you, you can read more about it here

void Main()
{
    using (AppContext context = new AppContext())
    {
        context.Users.AddOrUpdate(...);
    }
}

public class AppContext : DbContext
{
    public DbSet<User> Users { get; set; }


}

public class User 
{
    public string UserId { get; set; }
    public string Name { get; set; }
}

      


EDIT



This answer was skipped twice because it apparently was not thread safe. This might come as a surprise to some, but Entity Framework, as a framework, is not thread safe.

MSDN DbContext - Thread Safety

All public static (Shared in Visual Basic) members of this type are thread safe. Any member of the instance is not guaranteed to be thread safe.

Basically, the thread safety of my solution is irrelevant, as any use of the entity framework DbContext (in particular the SaveChanges / SaveChangesAsync methods) via parallel threads is going to give you questions like, out of the box.

+1


source







All Articles