2012-05-08 5 views
0

データベースへのラウンドトリップを排除するために、エンティティフレームワークを操作

List<Query> l = new List<Query>; 
// Query is a class that doesn't exist, it represents an EF operation 

foreach (var x in Xs) 
{ 
    Query o = { context.someEntity.Where(s=>s.Id==x.Id).First();} 
    // It wouldn't execute it, this is pseudo code for delegate/anonymous function 
    l.Add(o) 
} 
のは、私は(私はパフォーマンスが向上するように変更 簡単可能性を知っているが、それは私が何をしたいのか示して)次のコードのビットを持っているとしましょう

次に、このクエリのリストをEFに送信し、最小限の往復を可能にするように最適化します。それをBatchOptimizeAndRunと呼んでみましょう。あなたは言うでしょう

var results = BatchOptimizeAndRun(l); 

そして、それは最適なバージョンへの全体的なクエリを減らして、それを実行し、配列内の読み取り結果を置くだろうか、それはスキーマから知っている知っています。

私は正確に、より重要なのはそれが存在することを私が探していることを願っています。 もし私が散歩している狂った男のように聞こえたら、この質問は決して存在しないふりをしましょう。

+3

私の助言は、あなたの意志にEFを曲げようとしないことです。可能な限り活用し、不可能なところでそれを回避する。多くの場合、人々はこれを行うとコードを維持するのが難しいという混乱で終わり、とにかく短い時間でstraight ado.netを使用して動的でパラメータ化されたクエリを作成することができました。 EFに直接これに対処する機能がある場合は、明らかにそれを使用する必要がありますが、それ以外の場合は別の方法で行うと言います。 –

答えて

2

ムーア氏のアドバイスをエコーし​​なければならないのは、あまりにも長い時間をかけて、モノリシックな比率のlinq-to-entitiesクエリを作成して、ストアドプロシージャを短時間で作成できた読みやすく、速く実行できます。それは、私は、これはあなたが必要なものを提供します

SELECT 
    * 
FROM 
    someEntity 
WHERE 
    Id IN (ids) --Where ids is a comma separated list of INT 

のようなものにコンパイルされますと信じて...あなたの例では

List<int> ids = Xs.Select(x => x.Id).ToList(); 
var results = context.someEntity.Where(s => ids.Contains(s.Id)).ToList(); 

を言われています。