【问题标题】:LINQ for multiple count operations用于多个计数操作的 LINQ
【发布时间】:2012-01-04 20:13:07
【问题描述】:

@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 子句的能力),如果我可以避免它,我不想放弃它。还有其他解决方法吗?

【问题讨论】:

    标签: asp.net sql linq


    【解决方案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
    

    【讨论】:

      【解决方案2】:

      也许如果您使用复合键运行另一个查询来获取子组,它会转换为更高效的 SQL。我不了解我的 VB Linq 语法,因此请考虑以下伪代码:

      From d in db 
      Group d.a.AuditStatus By New With { d.a.AuditStatus, d.a.DateCreated } Into Group 
      Select ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-10-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多