9

ObjectContextにRejectChanges()メソッドがあるRIAサービスを使用していました。ただし、現在デスクトップアプリケーションでEF 4.4を使用しているので、その方法が見つかりません。したがって、私の質問は、ユーザーがコレクションに対してバッチCrUD操作を実行できるようにするシナリオで、すべての変更を元に戻すにはどうすればよいですか?コンテキストを再作成してデータを再度フェッチすることもできますが、変更を1〜2エンティティに戻す必要がある場合は、これは非常に不要に聞こえます。

では、変更を拒否する最良の方法は何ですか?また、コンテキストが何かを実行しているかどうかをどのように知ることができますか(IsBusy)?

4

5 に答える 5

12

EFには、直接の「変更の拒否」操作はありません。ChangeTracker/内のエンティティエントリを調べて、ObjectStateManager現在の値を変更されたエンティティの元の値で上書きできます。追加されたエンティティを切り離して、削除されたエンティティを変更されていないものに戻すこともできますが、ほとんどの場合、あなた(または内部的にEF)が独立した関連付け(関係)の状態を変更しなかった場合にのみ機能します。リレーションを操作する場合も、リレーションを元に戻す必要があるため、全体がはるかに複雑になる可能性があります。このような場合、データの再読み込みが簡単になります。

DbContext APIの変更を元に戻すには、次のことを試してください。

foreach (var entry in context.ChangeTracker
                             .Entries<YourEntityType>()
                             .Where(e => e.State == EntityState.Modified))
{
    entry.CurrentValues.SetValues(entry.OriginalValues);
}

この場合、主な問題はエンティティの操作方法だと思います。ライブデータの変更を許可し、EFは変更が実行されたときにデータの一貫性を維持するために背後でロジックを実行しますが、後でそれらの変更は保存されないことを決定します。 。この場合、次のいずれかを実行する必要があります。

  • 変更されたデータを破棄し、データセット全体をリロードします(コンテキストを再作成することにより)
  • このロジックを分離して、ライブデータで機能しないようにし、変更が実際に確認された場合にのみデータ変更をEFコンテキストにプッシュします

あなたが何かをするためにそれを言うならば、文脈は何かをしている。それ自体が忙しくなることはありません。

于 2012-05-10T14:47:51.690 に答える
11
public void RejectChanges()
        {
            foreach (var entry in ChangeTracker.Entries())
            {
                switch (entry.State)
                {
                    case EntityState.Modified:
                        {
                            entry.CurrentValues.SetValues(entry.OriginalValues);
                            entry.State = EntityState.Unchanged;
                            break;
                        }
                    case EntityState.Deleted:
                        {
                            entry.State = EntityState.Unchanged;
                            break;
                        }
                    case EntityState.Added:
                        {
                            entry.State = EntityState.Detached;
                            break;
                        }
                }
            }
        }
于 2014-02-28T13:56:21.453 に答える
2

私はこれが古い質問であることを知っています。しかし、私の状況に合う答えはありません。コレクション内の1つのエンティティのみの変更を拒否する必要がありました。これは私のために働いたものです:

    var objectContext = (myDbContext as IObjectContextAdapter).ObjectContext;
    objectContext.Refresh(RefreshMode.StoreWins, partMaster);
于 2014-01-20T22:47:04.320 に答える
1

これは私のために働きます:

public void RejectChanges() {
    var context = ((IObjectContextAdapter)this).ObjectContext;
    foreach (var change in this.ChangeTracker.Entries()) {
        if (change.State == EntityState.Modified) {
             context.Refresh(RefreshMode.StoreWins, change.Entity);
        }
        if (change.State == EntityState.Added) {
             context.Detach(change.Entity);
        }
     }
}

この場合、this =DbContext

于 2012-07-10T12:54:41.307 に答える
0

これは古い答えかもしれませんが、新しい訪問者には役立ちます。リロード機能は、データソースからオブジェクトをリロードし、既存の変更を上書きし、新しくロードされたエンティティのステータスは変更されません。

public static void UndoEntityChanges(object Entity)
{
    <EFModelContainer>.Entry(Entity).Reload();
}
于 2015-06-12T21:34:33.147 に答える