@gfrizzle指出here LINQ to SQL在给定LINQ时为每个计数操作生成独立的SELECT语句:
From d in db
Group d.a.AuditStatus By d.a.DateCreated Into Group
Select _
DateIssued = DateCreated, _
TotalAudits = Group.Count(), _
TotalCancelled = Group.Count(Function(x) If(x = "Cancelled", True, False)), _
TotalComplete = Group.Count(Function(x) If(x = "Complete", True, False)), _
TotalIssued = Group.Count(Function(x) If(x = "Issued", True, False)), _
TotalPending = Group.Count(Function(x) If (x = "Pending", True, False)), _
Remaining = 0
由于有问题的数据足够大,这很容易导致巨大的性能损失。我知道我可以将其重写为本机SQL查询,但我在其他地方使用LINQ的几个功能(比如能够破坏我的where子句),如果我可以避免它,我不想放弃它。还有其他解决方法吗?
答案 0 :(得分:1)
尤里卡!我终于明白了。这是构建底层SQL的一个逻辑问题。 无法将LINQ写为单一传递SQL查询,因为COUNT操作只查看行数,而不管任何WHERE样式子句。
解决方案是使用SUM代替模拟COUNT / WHERE组合。此LINQ查询使用SUM(CASE WHEN)列创建单个传递SQL查询。
From d In resultSet
Group d By key = d.a.DateCreated Into g = Group
Select _
TotalAudits = g.Sum(Function(x) 1), _
TotalCancelled = g.Sum(Function(x) If(x.a.AuditStatus = "Cancelled", 1, 0)), _
TotalComplete = g.Sum(Function(x) If(x.a.AuditStatus = "Complete", 1, 0)), _
TotalIssued = g.Sum(Function(x) If(x.a.AuditStatus = "Issued", 1, 0)), _
TotalPending = g.Sum(Function(x) If(x.a.AuditStatus = "Pending", 1, 0)), _
Remaining = 0
答案 1 :(得分:0)
也许如果您使用复合键运行另一个查询来获取子组,它可能会转换为更高效的SQL。我没有使用我的VB Linq语法,所以请考虑这个伪代码:
From d in db
Group d.a.AuditStatus By New With { d.a.AuditStatus, d.a.DateCreated } Into Group
Select ...