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

各RowVersionカラムに[Timestamp]という属性を追加する代わりに、流暢な設定を使用することをお勧めします。したがって、私のDbContextでは、各エンティティに対して、その列を行バージョンとして扱うよう指定します。

しかし、Entity 7は.IsRowVersion()オプションをサポートしていないようですが、 IsConcurrencyToken()オプションがありますが、最初の移行ではnull許容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とエンティティ7と並行処理を処理することですか?私がこのことに対処するのは初めてであり、どんな提案も感謝します。

UPDATE :リンク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()を使用して並行性トークンを構成することのみが可能です。

私は.IsRowVersion() APIを使って列全体を専用列でバージョン.IsRowVersion()する方法はまだ見つけられていません(流暢なAPIで.IsRowVersion()が許可されていればうれしいでしょうが、 .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は合法ですか? はい、理由を学ぶ