2012-01-04 90 views
0

@gfrizzle指出here給出LINQ時這樣說的LINQ to SQL生成獨立的SELECT語句爲每個計數操作:LINQ多個計數操作

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子句),如果我可以避免它,我不想放棄。任何其他解決方法?

回答

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 
0

也許如果您使用複合鍵運行另一個查詢來獲取子組,它會轉化爲更高效的SQL。我沒有注意到我的VB Linq語法,所以考慮這個僞代碼:

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

試過了,沒什麼區別。 – 2012-01-05 21:30:20