Entity Framework Core Add if not exist

Viewed 317

I use this code

using Microsoft.EntityFrameworkCore.ChangeTracking;

public static class DbSetExtensions
{
    public static EntityEntry<T> AddIfNotExists<T>(this DbSet<T> dbSet, T entity, Expression<Func<T, bool>> predicate = null) where T : class, new()
    {
        var exists = predicate != null ? dbSet.Any(predicate) : dbSet.Any();
        return !exists ? dbSet.Add(entity) : null;
    }
}

and

var purchase = new Models.Purchase();
var trackingnumber= "222";
_context.Purchases.AddIfNotExists(purchase, p => p.BankTrackingNum == trackingnumber);
await _context.SaveChangesAsync();

“Read before write” can violate data integrity without being put inside a transaction control.

In SQL Server, we can use merge statement. but merge statement is not available in EF. Do you know the solution other than transactions?

1 Answers

This is actually the proper way to do it, uniqueness of the key will come ( and be validated ) from the persistence layer. Your "read before write" can cause no problem at all, but "an other's write while you read and try to write" would cause an issue.

This is the proper way to do it, you could even throw the check away since the db will always throw, and just handle the "duplicate key" exceptions on purpose, just make sure proper constraints are in place.

For the main problem you can not do much unless you distribute-lock the code ( assuming you control all calls ). Race conditions are a real thing but not likely to happen.

Related