2009-08-21 14 views
0

私は、次のLINQのコードを持っていた:私はその後、それぞれの新しいTOARequestListSummaryオブジェクトを構築unsatifiedRequests上foreachをしたLinqの選択クエリでカウントとグループを使用するにはどうすればよいですか?

var allRequests = model.GetAllRequests(); 

    var unsatisifedRequests = (from request in allRequests 
           where request.Satisfied == false 
           select request) 
           .OrderBy(r => r.RequestedOn) 
           .GroupBy(r => r.RequestedCountryId); 

た後。これは、クエリから4つの項目を返すと、個々の行を取得するためにforeachのループごとに1回、DBへの4回の呼び出しを行います。

これは、LINQのを使用するために間違った方法であると思われるので、私はTOARequestListSummaryオブジェクトを直接返すために突起部を使用したものに、このクエリを変換しようと私が思い付いた:

var summaries = (from request in allRequests 
          where request.Satisfied == false 
          group request by request.RequestedCountryId into requestGroups 
          select new TOARequestListSummary 
          { 
           CountryName = requestGroups.First().RequestedCountry.Description, 
           RequestCount = requestGroups.Count(), 
           FirstRequested = requestGroups.First().RequestedOn 
          }); 

しかし、私は実行するとこれは、私は次の例外を取得:

Only one expression can be specified in the select list when the subquery is not introduced with EXISTS. 

私は限りLINQの当量はEXISTSすることを知ることが含まれているが、私は、クエリにこれをindroduceする方法が分からないとして持っています。

答えて

3

これはあなたのために働く必要があります。

var summaries = (from request in allRequests 
       where request.Satisfied == false 
       group request by request.RequestedCountry into g 
       select new TOARequestListSummary 
       { 
        CountryName = g.Key.Description, 
        RequestCount = g.Count(), 
        FirstRequested = g.Min(i => i.RequestedOn) 
       }); 

をこのクエリ(あなたが掲示秒1)の元のバージョンでは、あなたのグループのキーがRequestedCountryIdました。これは技術的にはグループ化されますが、実際には関連付けられたオブジェクトを使用したいと考えています。この方法で、必要なプロパティに簡単にアクセスでき、最初の項目を取得する心配はありません。

+0

実際、これはあまり正しくありません。私の例では、 'RequestedOn'は' RequestedCountry'オブジェクト上にあると仮定されていますが、あなたは 'request'自体にそれを持っています。 'FirstRequested'を特定する方法がありますか?もしそうでなければ、上記のように 'requestGroups.First()。RequestedOn'を使うことができます。あなたが最小または最大(または他の方法)をしたい場合、私はそれを修正するために変更することができます。 –

+0

RequestedOnはDateTime列です。最初に要求されたものがリストの一番上に表示されるように、それらを注文しようとしていました。 私はあなたの答えでコードを試してみましたが、gはCountry obejcts(RequestedCountryの型)のコレクションであるので、.Requested onはコンパイルされません。 私はg.First()を試してみましたが、次のような苦情がありました: メンバ 'Logica.Aurora.Data.Entities.TOARequest.RequestedCountry'にはSQLへの変換がサポートされていません。 これはグループ化できないことを意味しますか? –

+0

'RequestedCountry'はあなたのDB関係から自動的に生成されたプロパティですか? 'FirstRequested'はそのグループの最も古い' request'でしょうか、それとも最も古い 'request'の日付であるべきですか? –

0

申し訳ありませんが、これは非常に奇妙な取得...

これが答えではなく、ライアンの答えに追加のコメントですが、収まらには長すぎます。 LinqPadでは以下の御馳走に動作します

from request in TOARequests 
where request.Satisfied == false 
&& request.Active == true 
orderby request.RequestedOn 
group request by request.RequestedCountry into g 
select new 
{ 
    CountryName = g.Key.Description, 
    RequestCount = g.Count(), 
    FirstRequested = g.First().RequestedOn 
} 

をしかし、次は

var summaries = (from request in context.Repository<TOARequest>() 
          where request.Satisfied == false 
          && request.Active == true 
          orderby request.RequestedOn 
          group request by request.RequestedCountry into g 
          select new 
          { 
           CountryName = g.Key.Description, 
           RequestCount = g.Count(), 
           FirstRequested = g.First().RequestedOn 
          }).ToList(); 

唯一の違いは、私が見ることができますC#で同じ変換例外をスローした場合ToListメソッド()、しかし、それさえもせずときに私をリストを列挙しようとすると、例外がスローされます。

+1

おそらく 'FirstRequested = g.Min(i => i.RequestedOn)'を使い、orderbyを取り除きたいと思うでしょう(私の最近の編集のように)。私はまだそれが正常に(LinqPadに示されているように)動作する必要がありますので、あなたはそのSQLの変換例外を取得している理由はまだ分かりません。 –

+0

ありがとう、ミンは素晴らしい作品です。私はLinqPadでうまく動作するので、なぜそれがコードで動作しないのか分かりません。御時間ありがとうございます。 –

+0

私はLinqPadで動作するようにあなたの前の答えを正確にマークしました。私のコードでは何か変わったことがあるはずです。 –

関連する問題