Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
261 views
in Technique[技术] by (71.8m points)

c# - 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?

question from:https://stackoverflow.com/questions/65951311/best-practice-to-handle-concurrency-in-ef-core-and-asp-net-core

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...