web-dev-qa-db-ja.com

Entity Framework 6.xが結果をキャッシュしないのはなぜですか?

おそらくDbContextDbSetが行うキャッシングを誤解しているのかもしれませんが、キャッシングが続くという印象を受けました。次のコードを実行したときに予期しない動作が見られます。

var ctx = CreateAContext();
var sampleEntityId = ctx.SampleEntities.Select(i => i.Id)
                                       .Single(i => i == 3); //Calls DB as expected
var cachedEntityId = ctx.SampleEntities.Select(i => i.Id)
                                       .Single(i => i == 3); //Calls DB unexpectedly

何が起きてる? DbSetから得られるものの一部は、データベースを照会する前にそのオブジェクトが存在するかどうかを最初にローカルキャッシュで確認することだと思いました。ここに欠けている設定オプションのようなものはありますか?

39
Adam Modlin

@ emcas88が言おうとしている は、DbSet.Findメソッドを使用した場合にのみEFがキャッシュをチェックすることです。

.Single.First.Whereなどを使用しても、2次キャッシュを使用していない限り、結果はキャッシュされません。

42
danludwig

これは、extensorメソッドの実装では、コンテキストのFindメソッドを使用するためです

contextName.YourTableName.Find()

最初にキャッシュを検証します。それが役に立てば幸い。

29
emcas88

時々私の拡張メソッドを使用します:

using System.Linq;
using System.Linq.Expressions;

namespace System.Data.Entity
{
    public static class DbSetExtensions
    {
        public static TEntity FirstOrDefaultCache<TEntity>(this DbSet<TEntity> queryable, Expression<Func<TEntity, bool>> condition) 
            where TEntity : class
        {
            return queryable
                .Local.FirstOrDefault(condition.Compile()) // find in local cache
                   ?? queryable.FirstOrDefault(condition); // if local cache returns null check the db
        }
    }
}

使用法:

db.Invoices.FirstOrDefaultCache(x => x.CustomerName == "Some name");

FirstOrDefaultをSingleOrDetfaultに置き換えることもできます。

23
cryss

EF Docs を見てください。答えが見つかります:

DbSetとIDbSetは常にデータベースに対してクエリを作成し、返されたエンティティが既にコンテキストに存在していても、常にデータベースへのラウンドトリップを伴うことに注意してください。次の場合に、データベースに対してクエリが実行されます。

  • foreach(C#)またはFor Each(Visual基本)ステートメント。
  • ToArrayToDictionaryToListなどのコレクション操作によって列挙されます。
  • FirstAnyなどのLINQ演算子は、クエリの最も外側の部分で指定されます。
  • 次のメソッドが呼び出されます:LoadDbSet拡張メソッド、DbEntityEntry.Reload、およびDatabase.ExecuteSqlCommand
11

EF6はootbをキャッシュする結果を行いません。結果をキャッシュするには、2次キャッシュを使用する必要があります。 CodePlexでこの有望なプロジェクトを参照してください。

EF 6.1の第2レベルキャッシング

データベースのデータが変更されても、すぐにそれを知ることはできないことに注意してください。これはプロジェクトによっては重要な場合があります。 ;)

7
Dave