我有这个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'
答案 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 }
子句只是重用let
和orderby
中的表达式。
但是在LINQ中你有另一种选择 - 如果select
内的(OwnerId, Year)
组合看起来是唯一的,而不是OwnerYears
模式后跟left outer join
和{{ 1}}过滤空值您可以使用简单group join运算符与常规group by
调用:
Count