1

3 層のシナリオで自己追跡エンティティを使用して EntityFramework 4 を使用しています。
私の目標は、エンティティがサーバーに保存されたときに、ObjectContext の SavingChanges ハンドラーで変更されたプロパティを検出することです。

ご了承ください:

  • これは 3 層のシナリオです。そのため、Self-Tracked Entity は、フェッチされたものとは別の ObjectContext に保存されます
  • SaveChanges を呼び出す前に Self-Tracked Entity がコンテキストにアタッチされ、すべての変更が期待どおりに保存されます。


変更されたプロパティを追跡するために私が行うことは次のとおりです。

var objectStateManager = objectContext.ObjectStateManager;
var modifiedObjectStateEntries = objectStateManager
                    .GetObjectStateEntries(EntityState.Modified)
                    .Where(x => !x.IsRelationship);
foreach (modifiedObjectStateEntries の var modifiedObjectStateEntry)
{
    // このエンティティは別のコンテキストで取得されたため、データソースから更新する必要があります
    objectContext.Refresh (RefreshMode.ClientWins, modifiedObjectStateEntry.Entity);
    var modifiedProperties = modifiedObjectStateEntry.GetModifiedProperties();
}


何らかの理由で、変更されたプロパティだけでなく、すべてのプロパティが modifiedProperties コレクションに含まれるようになりました。これが事実である理由は何ですか?

OriginalValues と CurrentValues を比較すると、すべてが期待どおりに見えます。

var originalValues = modifiedObjectStateEntry.OriginalValues;
var currentValues = modifiedObjectStateEntry.CurrentValues;
for (int i = 0; i < originalValues.FieldCount; i++)
{
    // これは正常に動作し、差分のみが検出されます
    if (!Equals(originalValues.GetValue(i), currentValues.GetValue(i)))
    {
    }
}


なぜ「modifiedObjectStateEntry.GetModifiedProperties();」この場合、期待どおりに動作しませんか?


時間をありがとう、
コーエン

4

1 に答える 1

1

私が考えることができる唯一の理由は、最後の SaveChanges が発行された後に変更された場合にのみ、そのメソッドからの戻り値として表示されるため、すべてのプロパティを変更していることです。

MSDNで わかるように、最後に SaveChanges が呼び出されてから変更されたオブジェクトのプロパティの名前を返します

コード例を見ると、エンティティを更新しているためです (これにより、すべてのプロパティが設定され、変更済みとしてマークされます)。

...    
objectContext.Refresh(RefreshMode.ClientWins, modifiedObjectStateEntry.Entity);
...

この呼び出しは、変更されたものだけでなく、すべてのプロパティをリセットします。

あなたが達成しようとしていることは私には明らかではありませんが、更新されたものを確認する場合は、このようにすることはできません。エンティティのコピーを作成して更新するだけで、変更されたフィールドを確認できますが、見苦しくなります。

于 2013-03-07T17:44:01.423 に答える