Best way to handle upbeat concurrency with Entity Framework 7

I am using ASP.NET 5 rc1 and Entity 7 rc1 on top of coreclr with the first sample code migration project.

I looked at how to manage concurrency in entities, but I could not find good updated information on the recommended concurrency processing methods for Entity 7.

I have several entities, they all implement the interface:

public interface IVersionedModel { byte [] RowVersion { get; set; } } 

such as in:

 public class User : IVersionedModel { public Guid UserId { get; set; } public string Name { get; set; } public byte[] RowVersion { get; set; } } 

Instead of adding the [Timestamp] attribute to each RowVersion column, I prefer to use a free configuration, so in my DbContext I specify for each object that I want this column to be treated as a version of the row.

However, Entity 7 no longer supports the .IsRowVersion() option but it has the IsConcurrencyToken() option, which should be sufficient, but in the first first code migrations it generates a varbinary zero column, and when inserting / updating rows it does not increase the number .

I wonder if it is best to control the version of each row, increasing the version when updating or inserting objects into the database. This is my dbcontext

 public class AppDbContext : DbContext { public AppDbContext() : base() { } public DbSet<User> Users { get; set; } public DbSet<Organization> Organizations { get; set; } public DbSet<Membership> Memberships { get; set; } public override int SaveChanges() { //increase entity version for concurrency purposes foreach(var dbEntityEntry in ChangeTracker.Entries() .Where(x => x.State == EntityState.Added || x.State == EntityState.Modified)) { IVersionedModel entity = dbEntityEntry.Entity as IVersionedModel; if(entity != null) { //Increase byte[] RowVersion? } } return base.SaveChanges(); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<User>().Property(u => u.RowVersion).IsConcurrencyToken(); modelBuilder.Entity<Organization>().Property(o => o.RowVersion).IsConcurrencyToken(); modelBuilder.Entity<Membership>().Property(m => m.RowVersion).IsConcurrencyToken(); } } 

Basically, my question is: how to handle concurrency with ASP.NET 5 and Entity 7? This is the first time I do this thing and any suggestion will be appreciated.

UPDATE : thanks to the link https://stackoverflow.com/users/1922568/joe-audette , provided that I found several answers, unfortunately, not all

According to http://docs.efproject.net/en/latest/modeling/concurrency.html#how-concurrency-tokens-work-in-ef it seems we can use the Timestamp annotation if we want to output a string or ConcurrencyCheck annotation to a property if we want to use a version based on a property (not the entire string).

The free API only allows you to configure the concurrency token using .IsConcurrencyToken()

I have not yet found a way through the free API for the version of the entire row with the selected column (it would be nice if the free API allowed .IsRowVersion() , but it is not)

+5
source share
1 answer

I created a static class to handle this and other missing functions of the EF7 ModelBuilder ( use with caution , not tested in production)

 public static class SqlServerModelBuilderExtensions { public static PropertyBuilder<decimal?> HasPrecision(this PropertyBuilder<decimal?> builder, int precision, int scale) { return builder.HasColumnType($"decimal({precision},{scale})"); } public static PropertyBuilder<decimal> HasPrecision(this PropertyBuilder<decimal> builder, int precision, int scale) { return builder.HasColumnType($"decimal({precision},{scale})"); } public static PropertyBuilder<byte[]> IsRowVersion(this PropertyBuilder<byte[]> builder) { return builder.HasColumnType("rowversion").IsConcurrencyToken().ValueGeneratedOnAdd(); } } 
+3
source

Source: https://habr.com/ru/post/1237000/


All Articles