質問: SQL Serverデータベースには複数のルックアップテーブルがあります。テーブルは、アプリケーションのドロップダウンメニューで使用されます。 **AddressType:** * ホーム * ビジネス **製品の種類:** * 本 * 食物 * エレクトロニクス データベースルックアップテーブルを継続的に読み取る代わりに、チームは`MemoryCache`または`Redis Cache`を適用したい(データベースの負荷を減らし、メモリ内のパフォーマンスを向上させる)。ただし、Entity Framework Core `DbContext`既にキャッシュがあります。 したがって、この場合、一定量の読み取り後に`DbContext`がすでにこれを行っている場合、テーブルをキャッシュすることに値がありますか? `DbContext`を介して`MemoryCache/Redis`キャッシュコードを追加すると役立つでしょうか?それとも不必要な層でしょうか?
回答: MicrosoftはEF Core 2.0であるように、EF Coreは1次キャッシュのみをサポートします。つまり、クエリの実行結果としてエンティティが実体化されると、Entity Framework Context(aka System.Data.Entity.DbContextクラス) EF Coreの第1レベルのキャッシュメカニズムはパフォーマンスをある程度向上させますが、データベースレベルでエンティティのレコードが変更され、Entity Frameworkコンテキストからローカルにキャッシュされたエンティティのコピーを引き続き使用するシナリオを考えてください。そのため、誤った結果セットが取得される状況になります。 したがって、この問題の回避策は、これらのエンティティをコンテキストから切り離すことです。これは、キャッシュされたアイテムのエビクションとも呼ばれる一次キャッシュからエンティティを削除することを効果的に意味します。デタッチが完了すると、エンティティが再度フェッチされ、データベースから新しいデータが確実に読み取られるようになります。 したがって、EF Coreの標準(OOB)の第1レベルのキャッシングメカニズムは完全とはほど遠いことがわかります。それはエラーを起こしやすい不格好なコードにつながり、長期的にはコードベースが複雑で維持できなくなる可能性がかなりあります。 EF Core OOBの第1レベルのキャッシュメカニズムには、他にもいくつかの欠点があります。 * より多くのオブジェクトとその参照がメモリに読み込まれると、コンテキストのメモリ消費量が指数関数的に増加する可能性があります。皮肉なことにパフォーマンスの問題が発生します。 * コンテキストの破棄が必要でないときに適切に行われないと、メモリリークが発生する可能性があります。 * 同時実行に関連する問題が発生する可能性は、データがクエリされて更新される時間とのギャップが大きくなるにつれて増加します。 したがって、分散アプリケーションのスケーリングの必要性を考えるとわかるように、キャッシングプロバイダーの使用を強くお勧めします。