如何在Linq中的选择查询中使用Count和Group?

时间:2009-08-21 09:46:58

标签: linq-to-sql

我有以下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);

之后,我对unsatifiedRequests进行了foreach,为每个构建了一个新的TOARequestListSummary对象。这意味着如果我从查询中“返回”了4个项目,它将对数据库进行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是包含的,但我不知道如何将它产生到查询中。

2 个答案:

答案 0 :(得分: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)
                 });

在此查询的原始版本(您发布的第二个版本)中,您论坛的密钥为RequestedCountryId。虽然这在技术上会对其进行分组,但实际上您希望使用关联的对象。通过这种方式,您可以轻松访问所需的属性,而无需担心抓取第一个项目。

答案 1 :(得分:0)

很抱歉,这是一个答案,而不是对Ryan的答案的额外评论,但它太长了不适合......

这很奇怪。在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
}

但是以下内容在C#

中引发相同的转换异常
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();

我可以看到ToList()的唯一区别,但是当我尝试枚举列表时,即使没有它,它也会抛出异常。