2

SQL CE データベースに支えられた WPF MVVM アプリケーションで Entity Framework と Code First アプローチを使用しています。別のプロパティ値の変更に応じて、そのプロパティ値の 1 つを単純に更新できるモデル クラスを設計しようとしています。基本的に、インスタンスが EF によって初期化された後に「自己追跡」する poco を定義する方法を探しています。答えが Code First を放棄することである場合、おそらくそれが唯一の実行可能なルートです (確信はありません)。基本的な例:

class ThingModel
{
    public int Id { get; set; }

    public bool OutsideDbNeedsUpdate { get; set; }

    private string _foo;

    public string Foo
    {
        get { return _foo; }

        set
        {
            if (_foo != value)
            {
                _foo = value;

                OutsideDbNeedsUpdate = true;
            }
        }
    }
}

ただし、上記の問題は、DbContext が実行時にインスタンスを初期化し、フィールドを設定するときはいつでも、私のクラスが応答で依存フィールドを時期尚早に設定していることです。言い換えれば、EF がインスタンスのフィールドの初期化を完了した後にのみ、poco クラスがこの特別な変更追跡を実行できるようにする単純なパターンを探しています。

ここでのソリューションのようなことができることはわかっています が、私のビジネス ケースでは、この特別な変更追跡を EF 変更追跡から分離する必要があります。つまり、上記の HasChanges プロパティの状態に関係なく、SaveChanges の機能が必要です。これは、エンティティの HasChanges プロパティを定期的にチェックし、外部データベース (EF DbContext をサポートするデータベースと同じではない) の依存値を更新できるようにしたいためであり、その間に EF DB に多くの変更/保存が発生する可能性があるためです。外部DBにプッシュします。したがって、DB のレコードにフラグを保持し、外部 DB への定期的な更新が発生したときにフラグを false にリセットすることを望んでいた理由です。

4

1 に答える 1

2

編集後、 ObjectMaterialized eventを使用できると思います。

このイベントは、すべてのスカラー プロパティ、複合プロパティ、および参照プロパティがオブジェクトに設定された後、コレクションが読み込まれる前に発生します。

これをあなたのコンストラクタに入れますDbContext

((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized +=
    HandleObjectMaterialized;

そして方法:

private void HandleObjectMaterialized(object sender, ObjectMaterializedEventArgs e)
{ }

問題は、メソッド本体に何を入れるかです。おそらく最も簡単な解決策は、インターフェイスを定義することです

interface IChangeTracker
{
    bool Materialized { get; set; }
    bool OutsideDbNeedsUpdate { get; }
}

追跡したいクラスにこのインターフェースを実装させます。

次に、次のHandleObjectMaterializedことができます。

var entity = e.Entity as IChangeTracker;
if (entity != null)
{
    entity.Materialized = true;
}

OutsideDbNeedsUpdateこの後、いつ内部的に設定できるかがわかります。


原文

一般に、副作用のあるプロパティを持つことはお勧めしません (より正確には、表現する状態を変更するよりも多くの副作用があります)。この規則には例外があるかもしれませんが、ほとんどの場合、プロパティ間に依存関係を持たせることはお勧めできません。

あなたの実際のコードが何であるかがわからないので、あなたが最善を尽くすことができることを少し推測する必要がありますが、ゲッターにロジックを入れることは可能かもしれません. ほんの一例:

public State State
{
   get { return this.EndDate.HasValue ? MyState.Completed : this._state; }
   set { this._state = value; }
}

これは相互の依存関係を削除しませんが、プロパティがアクセスされるまで効果の瞬間を遅らせます。あなたの場合、どれがより早くないかもしれませんSaveChanges()

もう 1 つの戦略は、両方のプロパティを一度に設定するメソッドを作成することです。メソッドには、特にその名前が明確に示す場合に、副作用があることが予想されます。のようなメソッドを持つことができますSetMasterAndDependent (string master)

現在、メソッドはデータ バインディングのシナリオでは便利ではありません。その場合は、ビュー モデルに両方のプロパティを設定させるか、上記のようにメソッドを呼び出すことをお勧めします。

于 2013-01-16T22:59:26.283 に答える