对于空组,LINQ计数返回1而不是零

时间:2017-06-19 16:22:30

标签: c# entity-framework linq group-by

我有这个SQL查询:

SELECT oy.ownerId, oy.Year,  COUNT(doc.Id) as docCount FROM aavabruf.owneryears oy 
left join vastdocuments doc
on oy.ownerId = doc.Ownerid and  oy.Year =  doc.Year
group by oy.ownerid, oy.year
order by docCount

它将documentCount显示为在vastdocuments表中没有文档匹配的OwnerId,Year对的ZERO。

我尝试使用建议的左外连接解决方​​案对LINQ做同样的事情:

from oy in OwnerYears
join doc in VaStDocuments on new {oy.OwnerId, oy.Year} equals new {doc.OwnerId , doc.Year} into docS
from docIfNull in docS.DefaultIfEmpty()
group oy by new {oy.OwnerId, oy.Year} into g
orderby g.Count() ascending
select new { OwnerId = g.Key.OwnerId,  Year = g.Key.Year, docCount = g.Count()}

但是,对于不存在于VastDocuments表中的OwnerId,Year组,我将docCount设为ONE,而不是ZERO。如果我删除

  

来自docS.DefaultIfEmpty()

中的docIfNull

行“空”组根本不会显示。

如何将Count视为零,就像在SQL查询中一样?我尝试了以下方法:

  

Count = docIfNull == null? 0:g.Count()

然而在这种情况下我收到一个错误:

  

当前上下文中不存在名称'docIfNull'

2 个答案:

答案 0 :(得分:5)

最简单的方法是计算非空值:

g.Count(x => x != null)

我建议在<{em> select之后移动订单,以免您重复:

select new { g.Key.OwnerId, g.Key.Year, DocCount = g.Count(x => x != null) } into result
orderby result.DocCount
select result

但是,我注意到目前你根本没有使用 docIfNull ...所以我怀疑你的加入并不是真正做你做的事情想要它。也许你应该使用

group docIfNull by new { oy.OwnerId, oy.Year } into g

答案 1 :(得分:3)

SQL COUNT函数忽略NULL值,而LINQ Count函数没有谓词计算所有内容,包括null s。

通过使用Count的谓词版本,您可以在LINQ中获得相同的结果(请注意group docIfNull,因此g元素的类型与{{1}相同}}):

docIfNull

from oy in OwnerYears join doc in VaStDocuments on new { oy.OwnerId, oy.Year } equals new { doc.OwnerId, doc.Year } into docS from docIfNull in docS.DefaultIfEmpty() group docIfNull by new { oy.OwnerId, oy.Year } into g let docCount = g.Count(doc => doc != null) orderby docCount ascending select new { OwnerId = g.Key.OwnerId, Year = g.Key.Year, docCount = docCount } 子句只是重用letorderby中的表达式。

但是在LINQ中你有另一种选择 - 如果select内的(OwnerId, Year)组合看起来是唯一的,而不是OwnerYears模式后跟left outer join和{{ 1}}过滤空值您可以使用简单group join运算符与常规group by调用:

Count