LINQ to SQL在连接条件下使用子查询多次左连接查询

时间:2015-11-16 17:21:10

标签: sql sql-server linq join subquery

我有一个SQL查询,它将子查询作为左连接的参数。

SELECT tblfLeaseDetail.Lease_Detail_ID,
       tblfPayment.Payment_Date,
       tblfAuthorization.Authorized,
       tblvVendor.Vendor_Name,
       tblvCounty.County
  FROM tblfLeaseDetail
  LEFT
  JOIN tblfPayment
    ON tblfPayment.Lease_Detail_ID = tblfLeaseDetail.Lease_Detail_ID
   AND tblfPayment.Payment_ID =
        ( SELECT TOP 1
                 Payment_ID
            FROM tblfPayment
           WHERE tblfPayment.Lease_Detail_ID = tblfLeaseDetail.Lease_Detail_ID
           ORDER BY Payment_Date DESC
       )
    LEFT
  JOIN tblfAuthorization
    ON tblfAuthorization.Lease_Detail_ID = tblfLeaseDetail.Lease_Detail_ID
   AND tblfAuthorization.Authorization_ID =
        ( SELECT TOP 1
                 Authorization_ID
            FROM tblfAuthorization
           WHERE tblfAuthorization.Lease_Detail_ID = tblfLeaseDetail.Lease_Detail_ID
           ORDER BY Authorized_Date DESC
       )
    LEFT JOIN tblvVendor
    on tblvVendor.Vendor_ID = tblfLeaseDetail.Vendor_ID
    LEFT JOIN tblvCounty
    on tblvCounty.County_ID = tblfLeaseDetail.County_ID

我试图将其转换为LINQ。到目前为止,这就是我所做的:

var leaseList = (from l in leases.tblfLeaseDetails
                             join a in leases.tblfAuthorizations on l.Lease_Detail_ID equals a.Lease_Detail_ID into la
                             from jla in
                                 (from aj in leases.tblfAuthorizations
                                  where aj.Lease_Detail_ID == l.Lease_Detail_ID
                                  orderby aj.Authorized_Date descending
                                  select aj.Authorization_ID).Take(1).DefaultIfEmpty()
                             join p in leases.tblfPayments on l.Lease_Detail_ID equals p.Lease_Detail_ID into lp
                             from jlp in 
                                 (from pj in leases.tblfPayments
                                  where pj.Lease_Detail_ID == l.Lease_Detail_ID
                                  orderby pj.Payment_Date descending
                                  select pj.Payment_ID).Take(1).DefaultIfEmpty()
                             join v in leases.tblvVendors on l.Vendor_ID equals v.Vendor_ID into lv
                             from jlv in lv.DefaultIfEmpty()
                             join c in leases.tblvCounties on l.County_ID equals c.County_ID into lc
                             from jlc in lc.DefaultIfEmpty()
                             select new LeaseViewModel()
                             {
                                 Lease_Detail_ID = l.Lease_Detail_ID,                                     
                                 Vendor_Name = jlv.Vendor_Name,                                  
                                 County = jlc.County,
                                 Authorization = jla.Authorized,
                                 Payment_Date = jlp.Payment_Date
                             }).Distinct()

这会在 jla.Authorized jlp.Payment_Date 中返回错误:

' INT'不包含'授权'的定义并且没有延期方法'授权'接受类型' int'的第一个参数可以找到

Payment_Date也有同样的错误。

为什么jla和jlp被认为是整数?如何使此查询有效?

修改

这是最终且有效的LINQ查询:

var leaseList = (from l in leases.tblfLeaseDetails
                             join a in leases.tblfAuthorizations on l.Lease_Detail_ID equals a.Lease_Detail_ID into la
                             from jla in la.DefaultIfEmpty()
                             where jla.Authorization_ID == (from aj in leases.tblfAuthorizations
                                  where aj.Lease_Detail_ID == l.Lease_Detail_ID
                                  orderby aj.Authorized_Date descending
                                  select aj.Authorization_ID).Take(1).FirstOrDefault()
                             join p in leases.tblfPayments on l.Lease_Detail_ID equals p.Lease_Detail_ID into lp
                             from jlp in lp.DefaultIfEmpty() 
                             where jlp.Payment_ID == (from pj in leases.tblfPayments
                                  where pj.Lease_Detail_ID == l.Lease_Detail_ID
                                  orderby pj.Payment_Date descending
                                  select pj.Payment_ID).Take(1).FirstOrDefault()
                             join v in leases.tblvVendors on l.Vendor_ID equals v.Vendor_ID into lv
                             from jlv in lv.DefaultIfEmpty()
                             join c in leases.tblvCounties on l.County_ID equals c.County_ID into lc
                             from jlc in lc.DefaultIfEmpty()
                             select new LeaseViewModel()
                             {
                                 Lease_Detail_ID = l.Lease_Detail_ID,
                                 Lease_ID = l.Lease_ID,
                                 XRef_Lease_ID = l.XRef_Lease_ID,
                                 Vendor_Name = jlv.Vendor_Name,
                                 Description = l.Description,
                                 County = jlc.County,
                                 Amount = l.Amount,
                                 Payment_Due_Date = l.Payment_Due_Date,
                                 Lease_Type = l.Lease_Type.ToString(),
                                 Location_ID = l.Location_ID,
                                 Active = l.Active,
                                 Expiration_Date = l.Expiration_Date,
                                 Authorization = jla.Authorized,
                                 Payment_Date = jlp.Payment_Date
                             }).Distinct();

1 个答案:

答案 0 :(得分:1)

这是因为您分别在jla和jlp中选择了int类型的Authorization_ID和Payment_ID。尝试以下查询,让我知道它是如何工作的。

        bool rval = false;
        IntPtr hWinStaOrig, hWinSta, hDesktop;
        Win32.DEVMODE dm = GetDevMode();
        Win32.DISPLAY_DEVICE d = new Win32.DISPLAY_DEVICE();
        d.cb = Marshal.SizeOf(d);
        if (Win32.EnumDisplayDevices(null, deviceID, ref d, 0))
        {
            if (((d.StateFlags & Win32.DisplayDeviceStateFlags.AttachedToDesktop) != 0) && 
                ((d.StateFlags & Win32.DisplayDeviceStateFlags.PrimaryDevice) == 0))
            {
                if (Win32.EnumDisplaySettingsEx(d.DeviceName, Win32.ENUM_CURRENT_SETTINGS, ref dm, 0) != 0)
                {
                    dm.dmPelsWidth = 0;
                    dm.dmPelsHeight = 0;
                    dm.dmFields = Win32.DmFlags.DM_POSITION | Win32.DmFlags.DM_PELSWIDTH | Win32.DmFlags.DM_PELSHEIGHT;
                    if (Win32.ChangeDisplaySettingsEx(
                        d.DeviceName,
                        ref dm,
                        IntPtr.Zero,
                        Win32.ChangeDisplaySettingsFlags.CDS_UPDATEREGISTRY | Win32.ChangeDisplaySettingsFlags.CDS_RESET, // | Win32.ChangeDisplaySettingsFlags.CDS_GLOBAL ,
                        IntPtr.Zero
                        ) == (int)Win32.DISP_CHANGE.SUCCESSFUL)
                    {
                        hWinStaOrig = Win32.GetProcessWindowStation();
                        hWinSta = Win32.CreateWindowStation("MyWinSta", Win32.CWF_CREATE_ONLY,
                            Win32.ACCESS_MASK.WINSTA_ALL_ACCESS | Win32.ACCESS_MASK.STANDARD_RIGHTS_ALL,
                            0);
                        if (hWinSta != IntPtr.Zero)
                        {
                            if (Win32.SetProcessWindowStation(hWinSta))
                            {
                                    hDesktop = Win32.CreateDesktop("MyDesktop", null, null, Win32.DF_ALLOWOTHERACCOUNTHOOK, Win32.ACCESS_MASK.MAXIMUM_ALLOWED, 0);
                                if (hDesktop != IntPtr.Zero)
                                {
                                    if (AttachDisplayDevice(deviceID))
                                    {
                                        IntPtr hDC = Gdi32.CreateDC(d.DeviceName, null, null, IntPtr.Zero);
                                        if (hDC != IntPtr.Zero)
                                        {
                                            Win32.RECT r;
                                            r.left = 10;
                                            r.top = 10;
                                            r.right = 400;
                                            r.bottom = 300;

                                            Gdi32.SetTextColor(hDC, 0xffffff);
                                            Gdi32.SetBkColor(hDC, 0x0);

                                            if (Win32.DrawText(hDC, "Hello, Bozo!", -1, ref r, Win32.DT_CENTER | Win32.DT_VCENTER | Win32.DT_SINGLELINE) == 0)
                                            {
                                                Console.WriteLine("DrawText failed!");
                                            }

                                            Console.Write("Press Enter to Continue...");
                                            Console.ReadLine();

                                            Gdi32.DeleteDC(hDC);
                                        }
                                        DetachDisplayDevice(deviceID);
                                    }
                                    if (!Win32.CloseDesktop(hDesktop))
                                    {
                                        Error("CloseDesktop");
                                    }
                                }
                                else
                                {
                                    Error("CreateDesktop");
                                }
                                if (!Win32.SetProcessWindowStation(hWinStaOrig))
                                {
                                    Error("SetProcessWindowStation Failed!");
                                }
                            }
                            rval = Win32.CloseWindowStation(hWinSta);
                        }
                        AttachDisplayDevice(deviceID);
                    }
                }
            }
        }
        return rval;
    }