简体   繁体   中英

Best practice to handle concurrency in EF Core and ASP.NET Core?

Currently I'm doing the following when inserting/updating and entity:

public async Task<IdentityResult> UpdateAsync(Model model, CancellationToken ct = default)
{
    var entity = await GetAsync(ct);
    if (entity == null)
    {
        return await CreateAsync(model, ct);
    }
    context.Entry(entity).State = EntityState.Detached;

    Update(model);
    model.ConcurrencyToken = Guid.NewGuid().ToString();

    await context.SaveChangesAsync();
    return IdentityResult.Success;
}

And the update method:

protected virtual T Update(T entity)
{
    var dbEntityEntry = context.Entry(entity);
    if (dbEntityEntry.State == EntityState.Detached)
    {
        dbSet.Attach(entity);
        dbEntityEntry.State = EntityState.Modified;
    }

    return entity;
}

This is working. But is there a better (generic) way to handle concurrency?

Yes, there is a generic way to manage concurrency in EF Core. You already did the first part by adding a column that will be manage the row version for each update but you're updating the concurrency token manually.

The best way is to let the DB to automatically update the concurrency token for you by using Timestamp . As explained in EF Core documentation :

A timestamp/rowversion is a property for which a new value is automatically generated by the database every time a row is inserted or updated. The property is also treated as a concurrency token, ensuring that you get an exception if a row you are updating has changed since you queried it. The precise details depend on the database provider being used; for SQL Server, a byte[] property is usually used, which will be set up as a ROWVERSION column in the database.

How to use it (sample from EF Core documentation):

public class Blog
{
    public int BlogId { get; set; }

    public string Url { get; set; }

    [Timestamp]
    public byte[] Timestamp { get; set; }
}

So don't have to update the Timestamp or ConcurrencyToken column because it will be done for you by the database.

The last part is to make sure to correctly handle the concurrency conflicts and let the user know that he/she is out of date. How to manage concurrency conflicts (they raise exception). You can follow what is explained here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM