2012-03-07 3 views
0

私はこのコードを持っている:料金表はより多くの10の値を持つ場合このLINQ式を最適化する方法は?

var query = from deal in db.Deals 
      where deal.EndDate >= DateTime.UtcNow 
      select deal; 

var priceList = filters.Price.GetPriceRangeList(); 
foreach(var price in priceList) 
{ 
    var startPrice = price.StartPrice; 
    var endPrice = price.EndPrice; 
    var priceResult = from deal in query 
      where (deal.DiscountPrice >= startPrice && deal.DiscountPrice <= endPrice) 
      select deal; 
    if(priceResult.Count() != 0) 
     priceResults = (priceResults == null) ? priceResult : priceResult.Union(priceResults); 
} 
query = priceResults != null ? query.Intersect(priceResults) : Enumerable.Empty<Deal>().AsQueryable(); 

私のクエリが遅いです。

私はフィルターとしてIntersectを使用しています。

これらのクエリを最適化するにはどうすればよいですか?最適化のための

+4

何が 'であります以下同じ結果を持っている必要がありますが、それは上記の3つの問題の代わりに各組合のための反復処理の

var query = (from deal in db.Deals where deal.EndDate >= DateTime.UtcNow orderby deal.DiscountPrice ascending select deal).ToList(); var priceResults = (from price in filters.Price.GetPriceRangeList() let startPrice = price.StartPrice let endPrice = price.EndPrice select query.SkipWhile(d => deal.DiscountPrice < startPrice) .TakeWhile(d => deal.DiscountPrice <= endPrice) ).SelectMany(x => x); 

を持っていないと信じてクエリ '? Btw、 'priceResult.Count()!= 0'を' priceResult.Any() 'に変更する必要があります。後者は1つのアイテムだけを繰り返しますが、すべてをカウントします。 –

+0

LINQ to Objects、LINQ to SQLなど?オブジェクト私はあなたのTakeWhileユニオン – jason

+1

LINQ私はそのようなリクエストを3回行います。if(!filters.City.All &&!filters.City.IsEmpty()) { var cities = filters.City.ToArray(); query =クエリ内の取引 cities.Any(i => i.Equals(deal.City.Name)) select deal; } ' – BILL

答えて

0

あなたはいくつかの問題を持っています。最初は、クエリがforeachループの繰り返しごとに実行されるということです。 ToListまたはToArrayを呼び出すと、一度だけ実行されることが保証されます 第2に、ユニオンは高価です。 foreachループの繰り返しごとにpriceResultを繰り返します。 第3に、カウントも繰り返しますpriceResultです。任意の要素があるかどうかを知りたい場合は.Anyを代わりに使用してください。しかし、私はあなたがそれを避けることができると思います。私が正しくあなたのコードを読んでいれば、私は、異なるが、一度だけ

+0

上SkipWhileによってquaranteedだとdeal.DiscountPrice> = startPriceをスキップすることができると思います – BILL

+0

価格以下PriceResults私はTimeと同様の質問をします。だから私はおそらく毎回主なクエリの前に必要なパラメータをソートする必要がありますか? – BILL

+0

私はあなたがビクターを意味するのか分かりません。実際のコードで投稿を更新すると、役立つかもしれません。私はかなり一般的なアイデアがまだ残っています。他に何もない場合は、順序付けられたセットを別の変数に割り当てることができます –

1

ひとつのアイデアは、StartPrice昇順でStartPriceDiscountPrice財産よりも高くなると、あなたの内側のクエリがちょうどトラバーサルを停止することができ、そのようにクエリをソートするために、次のようになります。

var query = from deal in db.Deals 
      where deal.EndDate >= DateTime.UtcNow 
      orderby deal.DiscountPrice ascending 
      select deal; 

.. 
foreach(..) 
{ 
    var startPrice = price.StartPrice; 
    var endPrice = price.EndPrice; 

    var queryLocal = query.SkipWhile(deal => deal.DiscountPrice < startPrice); 
    var priceResult = queryLocal.TakeWhile(deal => deal.DiscountPrice >= startPrice 
             && deal.DiscountPrice <= endPrice); 

    .. 
} 
+0

と私の問題は、あなたがすでに私があるため、これらの要求の間 を「昇順orderbyのdeal.DiscountPrice」を使用することはできません –

関連する問題