エンティティフレームワークの更新コンテキスト?


100

どうすればコンテキストを更新できますか?データベースのビューに基づくエンティティがあり、ビューへのナビゲーションプロパティを持つ1つのテーブルエンティティに対して更新を行った場合、エンティティは更新ですが、ビューは更新されず、新しい更新に従って更新されません... Dbデータ。ありがとう!

回答:


91

コンテキスト内のエンティティを更新する最良の方法は、コンテキストを破棄して新しいコンテキストを作成することです。

あなたがいる場合、実際にいくつかのエンティティを更新する必要があり、DbContextクラスとコードファーストアプローチを使用している、あなたが使用することができます

    public static void ReloadEntity<TEntity>(
        this DbContext context, 
        TEntity entity)
        where TEntity : class
    {
        context.Entry(entity).Reload();
    }

コレクションのナビゲーションプロパティを再読み込みするには、

    public static void ReloadNavigationProperty<TEntity, TElement>(
        this DbContext context, 
        TEntity entity, 
        Expression<Func<TEntity, ICollection<TElement>>> navigationProperty)
        where TEntity : class
        where TElement : class
    {
        context.Entry(entity).Collection<TElement>(navigationProperty).Query();
    }

リファレンス:https : //msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbentityentry.reload(v=vs.113).aspx#M : System.Data.Entity.Infrastructure.DbEntityEntry 。リロード


3
子ナビゲーションプロパティを再読み込みするためにこれを機能させることができません。
ポール

@Davidがある場合は使用context.ReloadNavigationProperty(parent, p => p.Children);できますclass Parent { ICollection<Child> Children; }
Jinjinov

EFコアでは、クエリを使用することができます()ので、たとえば)(ロードします。context.Entry(order).Collection(o => o.NavigationProperty).Query().Load();
Rubenisme

このソリューションが非常に高い評価を得ている理由がわかりません。context.Entry(entity).Collection <TElement>(navigationProperty).Query()は子コレクションを再ロードしません。コレクションを取得するために使用されるクエリを表すIqueryableのみを提供します。文字通り何もしません。
スタットラー

72
yourContext.Entry(yourEntity).Reload();

3
簡単な解決策をありがとう。RX_DID_RXのような拡張メソッドでこれをカプセル化する必要性はないと思います
Thomas

これは私にとって命の恩人でした。ありがとうございました!
ケビン

19
これはコレクションナビゲーションプロパティをリロードせず、エンティティエントリ自体のみをリロードすることに注意してください。
James Wilkins

28

DbContextApiを使用して特定のエンティティーを再ロードする場合、RX_DID_RXはすでに答えを提供しています。

ロードしたすべてのエンティティをリロード/リフレッシュしたい場合:

Entity Framework 4.1+(EF5またはEF 6)を使用している場合、DbContext API:

public void RefreshAll()
{
     foreach (var entity in ctx.ChangeTracker.Entries())
     {
           entity.Reload();
     }
}

entityFramework 4(ObjectContext API)を使用している場合:

public void RefreshAll()
{
     // Get all objects in statemanager with entityKey
     // (context.Refresh will throw an exception otherwise)
     var refreshableObjects = (from entry in context.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted
                                               | EntityState.Modified
                                               | EntityState.Unchanged)
                                      where entry.EntityKey != null
                                      select entry.Entity);

     context.Refresh(RefreshMode.StoreWins, refreshableObjects);
}

とにかく最高のアドバイスは、「短期間のコンテキスト」を使用することです。そうすれば、この種の問題を回避できます。

私はその問題についていくつかの記事を書いた:

https://christianarg.wordpress.com/2013/06/13/entityframework-refreshall-loaded-entities-from-database/


良いですね!!私の日を救った!
Radu D

15

Refreshメソッドを使用します。

context.Refresh(RefreshMode.StoreWins, yourEntity);

または、現在のコンテキストを破棄して新しいコンテキストを作成することもできます。


@JMKここで正確に何が機能しないのですか?私には問題なく動作するようです(EF 6.1.1)。
Sebastian Krysmanski、2015年

@SebastianKrysmanski私は1年近く前にコメントしましたが、おそらく修正されていますか?
JMK 2015年

5
私はそれがdbcontextではなく、objectcontextに対してのみ機能すると思います。それらの間の会話が必要です
batmaci '26 / 10/26

3
@batmaciこれは簡単に実行できます((IObjectContextAdapter)dbContext).ObjectContext
Daniel Z.

3
それは少し不完全であると述べられていませんでした。
user441521

6

MVC 4、EF 5ではcontext.Reload()が機能しなかったので、これを行いました。

context.Entry(entity).State = EntityState.Detached;
entity = context.Find(entity.ID);

そして、その正常な動作。


1

EF 6

私のシナリオでは、Entity Frameworkは新しく更新されたデータを取得していませんでした。その理由は、データがその範囲外で更新されたためです。フェッチ後にデータを更新すると問題が解決しました。

private void RefreshData(DBEntity entity)
{
    if (entity == null) return;

    ((IObjectContextAdapter)DbContext).ObjectContext.RefreshAsync(RefreshMode.StoreWins, entity);
}

private void RefreshData(List<DBEntity> entities)
{
    if (entities == null || entities.Count == 0) return;

    ((IObjectContextAdapter)DbContext).ObjectContext.RefreshAsync(RefreshMode.StoreWins, entities);
}

1
私はEF6と一緒です。なぜこれよりも優れているの_context.Entry(entity).Reload();ですか?
Csaba Toth

私が覚えている限り、.Reload()はEF6では使用できません。@CsabaToth
Mahbubur Ra​​hman

0

パフォーマンスが低下するため、Reloadを使用してdbコンテキストを更新することはお勧めできません。各操作を実行する前に、dbcontextの新しいインスタンスを初期化することは十分であり、ベストプラクティスです。また、各操作の最新のコンテキストを提供します。

using (YourContext ctx = new YourContext())
{
   //Your operations
}

6
Dude ..コンテキストを毎回ダンプすると、更新したくないものも更新されるため、実際にパフォーマンスの問題が発生します。
LuckyLikey 2017年

2
ユニットテストを書く能力に影響を与えるので、これはひどい考えです。コードがオフになり、新しいコンテキストがニュースになる場合、単体テスト中にそれはどのように機能しますか?
ビクター

5
あなたが批判をするのではなく、いくつかのサンプルを見せればそれは私や他の人にとって有用でしょう。
aog

小さなウェブサイトにはその罰金。
alikuli 2018

-7

私は自分の頭を何も傷つけませんでした!答えは非常に簡単でした-基本に戻りました...

some_Entities   e2 = new some_Entities(); //your entity.

更新/削除した後、この行を下に追加します-エンティティを再ロードします-ファンシーなシステムメソッドはありません。

e2 = new some_Entities(); //reset.

2
それは「うまくいく」でしょう-それはただひどい考えであり、他の結果をもたらすでしょう
アダム・ヘイ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.