Entity Framework には、AppDomain ごとのデータ キャッシュはなく、コンテキスト インスタンスごとのキャッシュのみがあります。
要求またはクエリごとに新しいコンテキストを作成する場合、空のキャッシュから開始すると、EF はデータベースからデータをフェッチします。
さらに、"コンテキスト インスタンスごとのキャッシュ" という用語は、エンティティが既にコンテキスト キャッシュに読み込まれている場合に EF がデータベースに対してクエリを実行しないという意味ではないため、誤解を招く可能性があります。このキャッシュがどのように機能するか、およびそれを活用する (または活用しない) 方法は次のとおりです。
DbSet<T>
または一般的に 上のすべての LINQ-to-Entities クエリIQueryable<T>
は、コンテキスト内にエンティティが既に存在するかどうかに関係なく、データベース クエリを実行します。ただし、クエリされたエンティティと同じキーを持つエンティティがコンテキストに既に存在する場合、EF はそのクエリの結果を破棄し、キャッシュされたエンティティ インスタンスを呼び出し元に返します。
クエリを実行した後、同じキーを持つエンティティが存在するかどうかを確認します。(複雑なクエリの場合、たとえば、を含むクエリでは、Include
返されるエンティティとキー値を認識できないため、このチェックを行うことができません。)
これがデフォルトの動作です ( MergeOption
is AppendOnly
)。この動作をOverwriteChanges
他のオプションに変更することはできますが、LINQ クエリが常にデータベース クエリを発行することを避けることはできません。
キーだけでエンティティをクエリするには、GetObjectByKey
or Find
( with DbContext
) を使用できます。これは、そのキーを持つエンティティがコンテキストに既にキャッシュされているかどうかを最初に確認し、次にこのキャッシュされたオブジェクトを返します。そうでない場合は、データベース クエリを実行してロードします。
EF の ChangeTracker にクエリを実行できます。これは、コレクションDbContext
を介してコンテキスト キャッシュにアクセスできる場合に特によくサポートされています。DbSet<T>.Local
Local
ここでの問題は、クエリが結果を返さない場合にデータベースを自動的にクエリするロジックがないことです。このロジックは手動で作成する必要があります。さらに大きな問題は、クエリLocal
が LINQ-to-Objects であり、LINQ-to-Entities ( Local
does not implement IQueryable<T>
, only IEnumerable<T>
) ではないことです。そのため、クエリを書き直して操作する必要があることがよくありますLocal
-たとえば、使用できませんInclude
ここでは、 anyEntityFunctions
を使用できません。大文字と小文字の区別などに関する文字列比較の動作が異なります。