2015-11-28 9 views
5

Używam ASP.NET 5 rc1 i Entity 7 rc1 zamiast coreclr z przykładowym projektem pierwszej migracji kodu.Najlepszym sposobem radzenia sobie z optymistyczną współbieżnością z Entity Framework 7

miałem przyjrzeć się, jak zarządzać współbieżności w jednostkach, ale nie mogłem znaleźć żadnego dobrego Aktualne informacje o zalecanych praktyk obsługi współbieżności dla Entity 7.

Mam kilka podmiotów, wszystkie one wdrożyć interfejs:

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

jak na przykład:

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

Zamiast dodawania atrybutu [Timestamp] do każdego kol RowVersion umn Wolę używać płynnej konfiguracji, dlatego w moim DbContext I dla każdej jednostki chcę, aby kolumna była obsługiwana jako wersja wiersza.

Jednak Podmiot 7 nie wydają się potwierdzać już opcją .IsRowVersion() ale ma opcję IsConcurrencyToken(), co powinno wystarczyć, ale w kodzie pierwszych migracji generuje zerowalne kolumny varbinary i podczas wstawiania/aktualizowania wierszy nie robi auto-inkrementacja.

Zastanawiam się, czy najlepszym rozwiązaniem jest jawnie zarządzać wersję każdym rzędzie poprzez zwiększenie wersji podczas aktualizowania lub wstawiania podmiotów w bazie .. To mój 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(); 
    } 
} 

Zasadniczo moje pytanie jest, jak obsługiwać współbieżność z ASP.NET 5 i Entity 7? Po raz pierwszy poradzę sobie z tym i każda sugestia zostanie doceniona.

UPDATE: Dzięki link https://stackoverflow.com/users/1922568/joe-audette warunkiem znalazłem kilka odpowiedzi, niestety nie wszystkie

Zgodnie http://docs.efproject.net/en/latest/modeling/concurrency.html#how-concurrency-tokens-work-in-ef wydaje możemy użyć Timestamp adnotacji jeśli chcemy wersję wiersza lub ConcurrencyCheck adnotacji na nieruchomości jeśli chcemy wersji opartej na właściwości (nie cały wiersz).

Fluent API pozwala tylko skonfigurować za pomocą tokena współbieżności .IsConcurrencyToken()

jeszcze nie znaleźli sposób płynny poprzez API do wersji cały wiersz z dedykowanej kolumnie (byłoby miło, gdyby biegły API umożliwiła .IsRowVersion(), ale to nie robi)

+0

Czy temat może zostać zmieniony na "optymistyczna współbieżność" zamiast współbieżności, ponieważ wprowadza w błąd? –

+0

Temat zmieniono na optymistyczną współbieżność. – iberodev

+1

Czy widziałeś tutaj dokumentację dotyczącą tokenów współbieżności? http://docs.efproject.net/en/latest/modeling/concurrency.html –

Odpowiedz

3

Utworzyłem statyczną klasę do obsługi tego i innych brakujących cech EF7 ModelBuilder (korzystanie z ostrożnością, nie testowane w środowisku produkcyjnym)

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(); 
    } 
} 
Powiązane problemy