2011-01-05 10 views
1

私は、Entity Framework v4.0のNHibernateのバックグラウンドから来ています。エンティティをObjectContextにロードすると、ObjectContextが存続している間はエンティティがキャッシュされることが期待されます( '1st level cache')。したがって、同じクエリが2回目に実行された場合、オブジェクトは既にObjectContextにあり、再度ロードする必要はありません。Entity FrameworkのObjectContext(v4.0)の奇妙な動作

は、このクエリを見ている:SQL Serverプロファイラで

 using (var context = new Model1Container()) { 
      //load entities from DB 
      var entities = context.Entity1Set.ToArray(); 
      //entities should now be cached in the context (1st level cache) 

      //why does this call not use the cached items? 
      entities = context.Entity1Set.ToArray(); 
     } 

を、私は両方のToArray()の呼び出しは、データベースクエリをトリガすることをはっきりと見ることができます。なぜ、2番目のクエリは、NHibernateの動作ではなく、DBのラウンドトリップが必要ですか?

ありがとうございます!

答えて

1

EF 4.0は、どちらも第一及び第2のレベルのキャッシュ、キャッシュのいずれかの形式をサポートしていません。

Hibernate第1レベルキャッシュに似ている1つの機能がEF 4.1で実装されました。

EF 4.1 Local Data

HTH

Riana

2

良い質問です。私はNHibernateを使用したことはありませんが、私はEntity Frameworkを昨年ほど使っています。

いくつかの点で、あなたが説明した動作は私にとって意味があります。データベース内のデータがコール間で変更されたらどうなりますか?たとえば、データベーステーブルに新しい行が追加されたかどうかを確認するために、Entity Frameworkはデータベースを再クエリする必要があります。

ただし、結果に対してLINQクエリを実行すると、Entity FrameworkがObjectContextから既存のエンティティをフェッチするため、データベースへの別のラウンドトリップは必要ありません。 NHibernateのがそうであるように

var newEntities = entities.Where(x=>x.id==1).ToList(); 
var newEntities2 = entities.Where(x=>x.id==1).ToList(); 
+0

は、コンテキストにすでにある特定のIDとしなければならない操作は、データベースへの別のラウンドトリップを必要としません。私の経験をもとに、合意しました。私にすべてのアイテムを与えるなどの一般的な操作は常にdbに移動します。 – e36M3

+0

これは驚くことではありません。エンティティ配列の.Where()メソッドを実行すると、実際にはLINQ to Objectsではなく、LINQ to Entitiesを使用することになります。 LINQ to Entitiesが一般にクエリの結果をキャッシュすることができるのでしょうか? – cheeesus

+0

別のこと:私たちのObjectContextが長生きすると、データベース内のデータが呼び出し間で変更される可能性がある場合、ObjectContext.Refreshを使用できます。ほとんどの場合、ObjectContextは非常に短命です。したがって、その存続期間中のデータベースの変更については気にしません – cheeesus

関連する問題