2013-03-21 14 views
12

データベースに対してクエリを実行するためにEF(dllバージョンは4.4)を使用しています。データベースには、コース情報を含む複数のテーブルが含まれています。実際にdbに送られたものを見てみると、大規模な、ほぼ1300行のSQLクエリがあります(サイズのためにここに貼り付けません)。Include()を使用すると、EFで大量のSQLクエリが生成されないようにするには

entities.Plans 
    .Include("program") 
    .Include("program.offers") 
    .Include("program.fees") 
    .Include("program.intakes") 
    .Include("program.requirements") 
    .Include("program.codes") 
    .Include("focuses") 
    .Include("codes") 
    .Include("exceptions") 
    .Include("requirements") 
where plans.Code == planCode 
select plans).SingleOrDefault(); 

は私が関連テーブルのそれぞれから情報を収集する際、サーバーに戻ることがないようにしたいが、このような大規模なクエリと私は思ったんだけど場合:私は、コンテキストに実行しているクエリは次のようになりますこれを行うにはより良い方法がありますか?

ありがとうございました。

+0

まあ、あなたは熱心な読み込みをしており、あなたのクエリはすべてのデータを一度に取得しようとしています。あなたはそこに問題として何を正確に見ていますか?他のオプションは、アクセスしようとするとEFによってバックグラウンドでフェッチされる仮想プロパティを使用して遅延読み込みを行うことですが、データベースへのラウンドトリップを望まないと指定しました。 –

+0

類似の回答があります。http://stackoverflow.com/questions/5521749/how-many-include-i-can-use-on-objectset-in-entityframework-to-retain-performance –

+0

私は私はこれを正しく見ているのだろうかと思っています。 1つの巨大なクエリ対いくつかの小さなクエリか、これを行うより良い方法があるかどうか。 – b3n

答えて

0

通常、where句の後に.Include()を追加できます。これは、あなたが望むものに合った情報だけを取り出して、それがあなたの質問を減らすかどうかを確認することを意味します。

+1

これは違いはありません。私はLINQPadでクエリを実行し、生成されたSQLはどちらの場合も同じです。 – b3n

+0

'where' where節とそれはまだ同じでしたか?奇妙に思える...私が示唆できるのは、ナビゲーションプロパティを試してみるだけですが、少し違うと思いますが、正直なところ、それらを完全に理解していません。 また、plansテーブルからfilter/where句を使用して情報を引き出すこともできます。次に、いくつかのjoin文を実行して、必要なものを取得します。コードはかなり簡潔ではありませんが、速度を上げる必要があります。 – Trent

0

あなたが熱心な読み込みを実行しているので、必要なエンティティを選択している場合はその罰金が適用されます。さもなければLazy Loadingと一緒に行くことができますが、指定したようにデータベースの往復は望ましくないので避けることができます。

私は、このクエリが複数回使用されている場合は、コンパイルされたクエリを使用することをお勧めします。パフォーマンスが向上するようにします。このリンクを介して

行く、あなたがしたい場合は... http://msdn.microsoft.com/en-us/library/bb896297.aspx

0

あなたがDbContextを使用している場合は、あなたのエンティティがすでに取得し、したがって、コンテキストに接続されている場合、あなたが見て、コンテキストに.Localプロパティを使用することができます。クエリは、前に実行していたし、あなたのルートPlanエンティティはすでに、おそらくそのサブエンティティはまた、まだヒットしませんナビゲーションプロパティを経由してそれらを参照して、あなたが積極的なロードを行いましたので、添付されているPlan.Code == planId、に基づいて接続されている場合

その文脈の生涯の間に再び彼らのためのDB。

このarticleは、.Localを使用すると役立ちます。

0

あなたはご参照エンティティを引き戻すというIncludeよりも投影を使用してわずかより簡潔なSQLクエリを取得することができるかもしれない:あなたはあなたの文脈上、この種の遅延読み込みを無効にした場合

var planAggregate = 
(from plan in entities.Plans 
    let program = plan.Program 
    let offers = program.Offers 
    let fees = program.Fees 
    //... 
    where plan.Code == planCode 
    select new { 
    plan 
    program, 
    offers, 
    fees, 
    //... 
    }) 
    .SingleOrDefault(); 

クエリの結果は、エンティティのナビゲーションプロパティに、クエリに含まれていたエンティティが設定されます。

(これはEF.dll v5.0でのみテストされていますが、EF.dll v4.4では.NET 4.0のEF5と同じように動作するはずです。 Include同様の形のクエリでは、SQLの500行のうち約70行を削除しています)。

1

少し遅れていますが、データが1日に1回しか変更されないため、インデックス付きビューを作成し、このビューをEFモデルに配置します。

関連する問題