使用Entity Framework 7處理樂觀並發的最佳方法

asp.net-core entity-framework-core

我使用ASP.NET 5 rc1和Entity 7 rc1而不是coreclr,帶有示例代碼第一次遷移項目。

我正在研究如何管理實體中的並發性,但我找不到有關Entity 7推薦的並發處理實踐的任何好的更新信息。

我有幾個實體,它們都實現了接口:

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

例如:

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

而是將屬性[Timestamp]添加到每個RowVersion列,我更喜歡使用fluent配置,因此在我的DbContext中,我為每個實體指定了我希望該列作為行版本處理。

然而,實體7似乎不再支持選項.IsRowVersion()但它有選項IsConcurrencyToken() ,這應該足夠但在代碼第一次遷移時它會生成一個可空的varbinary列,並且在插入/更新行時它不會自動增加

我想知道最好的辦法是在更新或在數據庫中插入實體時通過增加版本來顯式管理每行的版本。這是我的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();
    }
}

基本上我的問題是,如何使用ASP.NET 5和Entity 7處理並發?這是我第一次處理這件事,任何建議都會受到讚賞。

更新 :感謝鏈接https://stackoverflow.com/users/1922568/joe-audette提供了我找到了一些答案,不幸的是並非全部

根據http://docs.efproject.net/en/latest/modeling/concurrency.html#how-concurrency-tokens-work-in-ef ,如果我們想要版本行或ConcurrencyCheck註釋,我們似乎可以使用Timestamp註釋如果我們想要基於屬性(而不是整行)的版本,在屬性上。

流暢的API僅允許使用.IsConcurrencyToken()配置並發令牌

我還沒有找到一種方法通過流暢的API來使用專用列對整行進行版本化(如果流暢的API允許使用.IsRowVersion() ,它會很好,但它不會)

熱門答案

我已經創建了一個靜態類來處理EF7 ModelBuilder的這個和其他缺失的功能( 謹慎使用 ,未在生產環境中測試)

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


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因