SQL запрос "WHERE IN" для преобразования в LINQ - PullRequest
2 голосов
/ 11 октября 2011

Я пытаюсь найти способ преобразовать этот очень сложный SQL-запрос в LINQ, и я не могу разобраться со всеми встроенными предложениями "WHERE IN". Может быть, кто-то будет так любезен, чтобы протянуть мне руку помощи?

Вот код 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)
                            })

    });

1 Ответ

3 голосов
/ 11 октября 2011

Вы преобразуете оператор SQL IN в 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)
...