EF CoreとMySQLを使用して行バージョンを実装するより良い方法は?

asp.net-core c# entity-framework-core mysql

質問

私のモデルで次のフィールドを使用する場合:

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[Timestamp]
public DateTime RowVersion { get; set; }

列を次のように定義します。

`RowVersion` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

私はEFから適切な楽観的な並行性の動作を得ます。つまり、タイムスタンプを使用することに興奮しているわけではありません。 2人のクライアントが1秒以内に同じレコードを更新しようとする大きなチャンスはありませんが、確かに起こる可能性はありますか?

それで、それを念頭に置いて、毎回の更新時に原子的に1ずつ増加する単純な整数を好むでしょう。このようにして、競合を逃す可能性はありません。私は私の定義を次のように変更した:

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[Timestamp]
public long RowVersion { get; set; }

問題は、MySQLは自動的にこれをインクリメントしないということです。私はトリガーを作成しました:

CREATE TRIGGER update_row_version BEFORE UPDATE on client 
FOR EACH ROW
SET NEW.RowVersion = OLD.RowVersion + 1;

そして今、これはすべて動作します。 EFは必要なときにDbUpdateConcurrencyExceptionをスローし、タイミングウィンドウのために更新が失われることはありません。しかし、それはトリガを使用し、私は彼らがパフォーマンスのためにどれほど悪いかについて読んでいます。

それで良い方法がありますか?クライアント上でRowVersionインクリメントを実行するためにDbContextのSaveChanges()をオーバーライドするための方法(おそらくトリガが実際にこの2つの更新を毎回行うと仮定しています)

受け入れられた回答

わかりました。私は、トリガが必要なくてもうまくいくと思われる戦略を考え出しました。

私は単純なインターフェースを追加しました:

interface ISavingChanges
{
    void OnSavingChanges();
}

モデルは次のようになります:

public class Client : ISavingChanges
{
    // other fields omitted for clarity...


    [ConcurrencyCheck]
    public long RowVersion { get; set; }

    public void OnSavingChanges()
    {
        RowVersion++;
    }
}

そして、私は次のようにSaveChangesをオーバーライドしました:

    public override int SaveChanges()
    {
        foreach (var entity in ChangeTracker.Entries().Where(e => e.State == EntityState.Modified))
        {
            var saveEntity = entity.Entity as ISavingChanges;
            saveEntity.OnSavingChanges();
        }

        return base.SaveChanges();
    }

これはすべて期待通りに機能しています。 ConcurrencyCheck属性は、UPDATE SQLのSET句とWHERE句の両方にRowVersionフィールドを含めるためのEFを取得するためのキーでした。



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ