1

単一のデータ コンテキスト (1 回作成) があり、それを使用して同じデータベース レコードを複数回取得します。たとえば、同じ製品 ID を指定して同じ製品レコードを取得します。

たとえば を呼び出すたびにcontext.Products.Single(p => p.ProdID == 1)、context は製品エンティティの同じインスタンスを返しますが、毎回データベースにクエリを実行します。これは SQL Server Profiler に表示されます。

呼び出しの間にいくつかのプロパティを変更して、同じインスタンスが返されることを確認します。次の呼び出しでは、プロパティが変更されたインスタンスが返されます。

毎回データベースにクエリを実行するのはなぜですか?これを回避する方法はありますか?

4

2 に答える 2

2

これは、別のユーザーが最初の呼び出しと 2 番目の呼び出しの間にレコードを変更した可能性があるためです。

データが比較的静的な場合は、キャッシュ ソリューションを検討してください。

于 2012-06-25T22:50:31.747 に答える
1

ObjectContext.GetObjectByKey ( DbSet<T>.Findfor DbContext) を使用して、キーでエンティティをクエリできます。このメソッドは、指定されたキーを持つオブジェクトが既にコンテキストにアタッチされているかどうかを確認します。はいの場合、データベースにクエリを実行せずにそのオブジェクトを返します。コンテキストに存在しない場合は、データベース クエリを実行します。

LINQ クエリは通常、オブジェクトが既にコンテキストにアタッチされているかどうかに関係なく、データベースに対してクエリを実行します。EF は、クエリの結果がわからないため、オブジェクトがアタッチされているかどうかを前もって知ることができません。キーによるLINQクエリは例外です-理論的に-EFは、そのキーを持つオブジェクトが既にアタッチされているかどうかを確認できるため、クエリが必要かどうかを知ることができますしかし、この例外はそのようには処理されずGetObjectByKey、それが存在する理由であり、他のすべての LINQ クエリと同様にデータベースにクエリを実行します。

クエリの結果がどうなるかは、ObjectSet のMergeOptionによって決まります。デフォルトは ですAppendOnly。これは、キーを持つオブジェクトがすでにコンテキストにアタッチされている場合、クエリ結果が破棄されることを意味します。クエリによって上書きまたは更新されるものはありません。キーを持つオブジェクトがコンテキストに存在しない場合にのみ、クエリ結果のオブジェクトが具体化され、コンテキストにアタッチされます。別の を選択することで、このデフォルトの動作を変更できますMergeOption

于 2012-06-25T23:21:19.700 に答える