2015-11-28 5 views
5

Sto utilizzando ASP.NET 5 rc1 e Entity 7 rc1 su coreclr con un progetto di esempio per la prima migrazione.Il modo migliore per gestire la concorrenza ottimistica con Entity Framework 7

stavo avendo uno sguardo a come gestire la concorrenza in entità, ma non sono riuscito a trovare nulla di buono informazioni aggiornate circa le pratiche di manipolazione concorrenza consigliate per Entity 7.

Ho un paio di soggetti, tutti attuare la interfaccia:

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

come per esempio in:

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

Invece aggiungendo l'attributo [Timestamp] a ciascuna col RowVersion umn Preferisco usare la fluente configurazione, quindi nel mio DbContext specificherò per ogni entità che voglio che quella colonna sia gestita come la versione della riga.

Tuttavia Entity 7 non sembra supportare più l'opzione .IsRowVersion() ma ha l'opzione IsConcurrencyToken(), che dovrebbe essere sufficiente, ma in codice prime migrazioni genera una colonna varbinary Null e per inserire/righe aggiornamento non è così auto-incremento.

Mi chiedo se la cosa migliore da fare è quello di gestire in modo esplicito la versione di ogni riga, aumentando la versione per l'aggiornamento o l'inserimento entità nel database .. Questo è il mio 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(); 
    } 
} 

Fondamentalmente la mia domanda è, come gestire la concorrenza con ASP.NET 5 e Entity 7? È la prima volta che mi occupo di questa cosa e ogni suggerimento sarà apprezzato.

AGGIORNAMENTO: Grazie per il link https://stackoverflow.com/users/1922568/joe-audette fornito ho trovato alcune risposte, purtroppo non tutti

Come per http://docs.efproject.net/en/latest/modeling/concurrency.html#how-concurrency-tokens-work-in-ef sembra possiamo usare Timestamp annotazione, se vogliamo la versione di una riga o ConcurrencyCheck annotazione su una proprietà se vogliamo una versione basata su una proprietà (non sull'intera riga).

L'API fluente consente solo di configurare la concorrenza di token utilizzando .IsConcurrencyToken()

non ho ancora trovato un modo tramite l'API fluente alla versione l'intera riga con una colonna dedicata (sarebbe bello se il fluente API ha permesso un .IsRowVersion(), ma non è così)

+0

Il soggetto può essere modificato in "concorrenza ottimistica" anziché in concorrenza perché è fuorviante? –

+0

Oggetto cambiato in concorrenza ottimistica. – iberodev

+1

Hai visto la documentazione relativa ai token di concorrenza qui? http://docs.efproject.net/en/latest/modeling/concurrency.html –

risposta

3

ho creato una classe statica per gestire questa ed altre caratteristiche mancanti di EF7 ModelBuilder (utilizzare con cautela, non testato in un ambiente di produzione)

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(); 
    } 
}