2011-10-11 83 views
1

我試圖找到一種方法將這個非常複雜的SQL查詢轉換爲LINQ,而我似乎無法處理所有嵌入的「WHERE IN」子句。有人會如此善意地伸出援助之手嗎?SQL「WHERE IN」查詢轉換爲LINQ

下面是SQL代碼(不用擔心存儲過程,這是一個行總​​計的計數)

SELECT  
    (SELECT pac.Name FROM Account pac WHERE pac.AccountID = AC.ParentAccountID) AS ParentAccountName, 
    ac.Name, dv.DeviceID, dv.Manufacturer, dv.Model, dv.SerialNr, dv.PrinterIPAddress, 
    (SELECT TOP 1 au.AuditDate FROM PrinterAudit pa WITH (NOLOCK) INNER JOIN Audit au ON au.AuditID = pa.AuditID 
     WHERE pa.DeviceID=dv.DeviceID 
     ORDER BY AuditDate DESC) AS AuditDate, 
    dbo.Get_TotalPageCountByDeviceId(DATEADD(month, -3, GETDATE()), GETDATE(), dv.DeviceID) as TotalUsageLast3Months 
FROM Account ac WITH (NOLOCK) 
      INNER JOIN Device dv ON ac.AccountID = dv.AccountID 
WHERE dv.AccountID IN 
      (SELECT au.AccountID FROM Audit au WHERE au.AuditDate >= DATEADD(month, -3, GETDATE())) 
      AND (dv.Manufacturer + dv.Model) IN 
       (SELECT (dv2.Manufacturer + dv2.Model) 
       FROM Device dv2 
       WHERE dv2.AccountID = dv.AccountID 
       AND dv2.Manufacturer = dv.Manufacturer 
       AND dv2.Model = dv.Model 
       AND (dv2.ERPEquipID IS NOT NULL OR dv2.ERPData IS NOT NULL)) 
       AND dv.ERPEquipID IS NULL AND dv.ERPData IS NULL 
       AND dv.DeviceID IN 
       (SELECT pa.DeviceID 
       FROM PrinterAudit pa WITH (NOLOCK) 
       INNER JOIN Audit au ON au.AuditID = pa.AuditID 
       WHERE au.AuditDate >= DATEADD(month, -3, GETDATE())) 
ORDER BY ParentAccountName, ac.Name 

最終結果:

var result = 
    (from dv in Device 
    where Audit.Any(au => au.AuditDate >= DateTime.Now.AddMonths(-3) 
     && au.AccountID == dv.AccountID) 
    where Device.Any(dv2 => dv2.AccountID == dv.AccountID 
     && dv2.Manufacturer == dv.Manufacturer 
     && dv2.Model == dv.Model 
     && (dv2.ERPEquipID != null || dv2.ERPData != null) 
     && dv.ERPEquipID == null 
     && dv.ERPData == null 
     && PrinterAudit.Any(pa => pa.Audit.AuditDate >= DateTime.Now.AddMonths(-3) && pa.DeviceID == dv.DeviceID)) 
    orderby dv.Account.ParentAccountID, dv.Account.Name 
    select new 
    { 
     ParentAccountName = Account.Where(pac => pac.AccountID == dv.Account.ParentAccountID).Select(pac => pac.Name), 
     Name = dv.Account.Name, 
     DeviceID = dv.DeviceID, 
     Manufacturer = dv.Manufacturer, 
     Model = dv.Model, 
     SerialNumber = dv.SerialNr, 
     PrinterIPAddress = dv.PrinterIPAddress, 
     AuditDate = (from pa in PrinterAudit where pa.DeviceID == dv.DeviceID orderby pa.Audit.AuditDate descending select pa.Audit.AuditDate).Take(1), 
     TotalUsageLast3Months = (from p in PrinterAudit 
          where p.DeviceID == dv.DeviceID 
          group p by p.DeviceID into total 
          select new 
          { 
           Total = Get_TotalPageCountByDeviceId(DateTime.Now.AddMonths(-3), DateTime.Now, dv.DeviceID) 
          }) 

    }); 
+0

可能重複【如何做一個WHERE ...在...在LinqToSql條款?(http://stackoverflow.com/questions/317606/ how-to-do-a-where-in-clause-in-linqtosql) – jrummell

+0

這個例子的問題,我一直試圖整理出來大約一個月,是他們都只有一個WHERE IN子句。我有3個嵌套。這就是大部分困惑來臨的地方。 – GenXisT

+0

我給了初步答覆的答案,因爲它使我朝着正確的方向前進,現在我的結果集足夠正確。感謝您的快速準確的答覆。 – GenXisT

回答

3

將轉換爲SQL IN聲明與任何ContainsAny LINQ

包含

from dv in db.Device 
where 
    (from au in db.Audit 
    where au.AuditDate >= DateTime.Now.AddMonths(-3) 
    select au.AccountID).Contains(dv.AccountID) 

任何

from dv in db.Device 
where 
    db.Audit.Any(au => au.AuditDate >= DateTime.Now.AddMonths(-3) && 
       au.AccountID == dv.AccountID) 
+0

這是在Meta-Me博客中介紹的,請參閱https://blogs.msdn.microsoft.com/alexj/2009/03/25/tip-8-how-to-write-where-in-style-queries-using -linq到實體/ –