7

Asp.net でクエリごとに DbContext を作成すると、EF はそのキャッシュからのみデータを読み取るようになりますか、それとも毎回セット全体に対して DB をクエリしますか? AppDomain ごとのメタデータ キャッシュについては知っていますが、データだけについてはどうでしょうか。

コンテキスト: MVC4 + Web API フロントエンドを使用したデータ取得および視覚化アプリケーションは、それを「大量」とは呼びませんが、多くのクエリが短い時間枠で同じデータ セットを返します。

4

1 に答える 1

18

Entity Framework には、AppDomain ごとのデータ キャッシュはなく、コンテキスト インスタンスごとのキャッシュのみがあります。

要求またはクエリごとに新しいコンテキストを作成する場合、空のキャッシュから開始すると、EF はデータベースからデータをフェッチします。

さらに、"コンテキスト インスタンスごとのキャッシュ" という用語は、エンティティが既にコンテキスト キャッシュに読み込まれている場合に EF がデータベースに対してクエリを実行しないという意味ではないため、誤解を招く可能性があります。このキャッシュがどのように機能するか、およびそれを活用する (または活用しない) 方法は次のとおりです。

  • DbSet<T>または一般的に 上のすべての LINQ-to-Entities クエリIQueryable<T>は、コンテキスト内にエンティティが既に存在するかどうかに関係なく、データベース クエリを実行します。ただし、クエリされたエンティティと同じキーを持つエンティティがコンテキストに既に存在する場合、EF はそのクエリの結果を破棄し、キャッシュされたエンティティ インスタンスを呼び出し元に返します。

    クエリを実行した、同じキーを持つエンティティが存在するかどうかを確認します。(複雑なクエリの場合、たとえば、を含むクエリでは、Include返されるエンティティとキー値を認識できないため、このチェックを行うことができません。)

    これがデフォルトの動作です ( MergeOptionis AppendOnly)。この動作をOverwriteChanges他のオプションに変更することはできますが、LINQ クエリが常にデータベース クエリを発行することを避けることはできません。

  • キーだけでエンティティをクエリするには、GetObjectByKeyor Find( with DbContext) を使用できます。これは、そのキーを持つエンティティがコンテキストに既にキャッシュされているかどうかを最初に確認し、次にこのキャッシュされたオブジェクトを返します。そうでない場合は、データベース クエリを実行してロードします。

  • EF の ChangeTracker にクエリを実行できます。これは、コレクションDbContextを介してコンテキスト キャッシュにアクセスできる場合に特によくサポートされています。DbSet<T>.Local

    Localここでの問題は、クエリが結果を返さない場合にデータベースを自動的にクエリするロジックがないことです。このロジックは手動で作成する必要があります。さらに大きな問題は、クエリLocalが LINQ-to-Objects であり、LINQ-to-Entities ( Localdoes not implement IQueryable<T>, only IEnumerable<T>) ではないことです。そのため、クエリを書き直して操作する必要があることがよくありますLocal-たとえば、使用できませんIncludeここでは、 anyEntityFunctionsを使用できません。大文字と小文字の区別などに関する文字列比較の動作が異なります。

于 2013-06-11T19:05:45.907 に答える