SQL到LINQ重复的组计数

时间:2017-09-13 03:39:23

标签: c# sql-server linq group-by

我正在将SQL结果转换为LINQ。

SQL很简单:

select NAME, DESC, count(*) total from dbo.TBL_ITEM_BY_PROVIDER p 
inner join dbo.TBL_TYPE_PROVIDER tp on tp.id = p.provider_id
group by NAME, DESC SORT_ORDER
order by SORT_ORDER

输出很简单:

NAME    DESC                   Count(*)
CSD     Census and Statistics  5
LandsD  Lands Department       52
PlandD  Planning Department    29

我的LINQ:

from p in data.TBL_ITEM_BY_PROVIDERs
join tp in data.TBL_TYPE_PROVIDERs on p.PROVIDER_ID equals tp.ID
group new { p, tp } by new { tp.NAME, tp.DESC } into provider
orderby (provider.Key.NAME)
select new { 
    provider.Key.NAME, 
    provider.Key.DESC, 
    count = (from pp in provider select pp.tp.NAME.ToList().Count())
};   

并且输出是重复的计数数组:[5,5,5,5,5]

0:{NAME: "CSD", DESC: "Census and Statistics", count: [5, 5, 5, 5, 5]}
1:{NAME: "LandsD", DESC: "Lands Department", count: [52, 52, 52, 52...]}
2:{NAME: "PlandD", DESC: "Planning Department", count: [29, 29, 29, 29...]}

如何正确编写像SQL一样的组语句?

2 个答案:

答案 0 :(得分:1)

您可以稍微改写一下分组。由于您只想计算组中有多少项目,您可以:

var result = from p in data.TBL_ITEM_BY_PROVIDERs
             join tp in data.TBL_TYPE_PROVIDERs on p.PROVIDER_ID equals tp.ID
             group 1 by new { tp.NAME, tp.DESC } into provider
             orderby provider.Key.NAME
             select new {
                 provider.Key.NAME, 
                 provider.Key.DESC, 
                 Count = provider.Count()
             }; 

请注意,以下内容无法满足您的期望:

pp.tp.NAME.ToList().Count()

NAME是一个字符串。在其上执行ToList()会返回List<char>,因此Count()会计算字符串中的字母数。正如您在嵌套查询的select语句中所做的那样,您将获得计数的集合,而不是数字。

最后,请注意,在您的sql中,您的排序是order by SORT_ORDER,而您的linq是order by provider.Key.NAME - 不是相同的字段,只是偶然为这些数据提供了相同的所需排序< / p>

答案 1 :(得分:0)

根据documentation,LINQ group子句返回IGrouping<TKey,TElement>的序列。虽然IGrouping<TKey,TElement>实施IEnumerable<TElement>,但要计算组中的项目数,您只需调用Count()方法。

您还可以简化查询的group子句。

from item in data.TBL_ITEM_BY_PROVIDERs
join provider in data.TBL_TYPE_PROVIDERs
    on item.PROVIDER_ID equals provider.ID
group item by provider into itemsByProvider
orderby itemsByProvider.Key.NAME
select new
{
    itemsByProvider.Key.NAME,
    itemsByProvider.Key.DESC,
    count = itemsByProvider.Count()
};