在LEFT JOIN条件下使用子查询的LINQ查询

时间:2015-12-07 16:58:29

标签: c# sql asp.net-mvc linq left-join

我在SQL和LINQ中有这些查询,它们是为检索相同的数据而构建的。不幸的是,他们正在检索不同数量的记录(LINQ返回1555值,SQL返回1969),我无法弄清楚原因。

请帮助我找出我失踪的东西。按照查询:

SQL:

SELECT l.Lease_Detail_ID, l.Lease_ID, l.XRef_Lease_ID, v.Vendor_Name, l.Description, c.County, l.Amount, l.Payment_Due_Date,
    l.Lease_Type, l.Location_ID, l.Active, l.Expiration_Date, a.Authorized, p.Payment_Date
    FROM tblfLeaseDetail AS l
    LEFT JOIN tblvVendor AS v ON l.Vendor_ID = v.Vendor_ID
    LEFT JOIN tblvCounty AS c ON l.County_ID = c.County_ID
    LEFT JOIN tblfAuthorization AS a ON l.Lease_Detail_ID = a.Lease_Detail_ID
    AND a.Authorization_ID = (SELECT TOP 1 Authorization_ID
                            FROM tblfAuthorization
                            WHERE Lease_Detail_ID = l.Lease_Detail_ID
                            ORDER BY Authorized_Date)
    LEFT JOIN tblfPayment AS p ON l.Lease_Detail_ID = p.Lease_Detail_ID
    AND p.Payment_ID = (SELECT TOP 1 Payment_ID
                        FROM tblfPayment
                        WHERE Lease_Detail_ID = l.Lease_Detail_ID
                        ORDER BY payment_date)
    ORDER BY l.Lease_Detail_ID

LINQ: (在几条评论后编辑)

var leaseList = (from l in leases.tblfLeaseDetails
                         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()
                         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 ascending
                                                        select aj.Authorization_ID).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 ascending
                                                  select pj.Payment_ID).FirstOrDefault()
                         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,
                             Authorized = jla.Authorized,
                             Payment_Date = jlp.Payment_Date
                         });

修改

在分析LINQ语句生成的运行时SQL查询后,我发现它在错误的位置创建了授权子查询。这是它的样子:

SELECT [t0].[Lease_Detail_ID], [t0].[Lease_ID], [t0].[XRef_Lease_ID], [t1].[Vendor_Name] AS [Vendor_Name], [t0].[Description], [t2].[County] AS [County], [t0].[Amount], [t0].[Payment_Due_Date], [t0].[Expiration_Date], [t3].[Authorized] AS [Authorized], CONVERT(NVarChar(1),[t0].[Lease_Type]) AS [Lease_Type], [t0].[Location_ID], CONVERT(Int,[t0].[Active]) AS [Active], [t4].[Payment_Date] AS [Payment_Date]
FROM [dbo].[tblfLeaseDetail] AS [t0]
LEFT OUTER JOIN [dbo].[tblvVendor] AS [t1] ON [t0].[Vendor_ID] = ([t1].[Vendor_ID])
LEFT OUTER JOIN [dbo].[tblvCounty] AS [t2] ON [t0].[County_ID] = ([t2].[County_ID])
LEFT OUTER JOIN [dbo].[tblfAuthorization] AS [t3] ON ([t0].[Lease_Detail_ID]) = [t3].[Lease_Detail_ID]
LEFT OUTER JOIN [dbo].[tblfPayment] AS [t4] ON ([t0].[Lease_Detail_ID]) = [t4].[Lease_Detail_ID]
WHERE ([t4].[Payment_ID] = ((SELECT TOP (1) [t5].[Payment_ID] FROM [dbo].[tblfPayment] AS [t5] WHERE [t5].[Lease_Detail_ID] = ([t0].[Lease_Detail_ID]) 
                            ORDER BY [t5].[Payment_Date] ))) 
                            AND ([t3].[Authorization_ID] = (( SELECT TOP (1) [t6].[Authorization_ID] 
                                                                FROM [dbo].[tblfAuthorization] AS [t6] 
                                                                WHERE [t6].[Lease_Detail_ID] = ([t0].[Lease_Detail_ID]) 
ORDER BY [t6].[Authorized_Date] )))

问题是,一旦付款和授权联接具有完全相同的结构,它就会变得更加混乱。

1 个答案:

答案 0 :(得分:0)

经过一番研究,我终于找到了如何做到这一点。这是生成我试图得到的SQL的LINQ查询:

var leaseList = (from l in leases.tblfLeaseDetails
                             join p in leases.tblfPayments
                             on l.Lease_Detail_ID equals p.Lease_Detail_ID into lp
                             from jlp in lp.Where(x => x.Payment_ID == (from pj in leases.tblfPayments
                                                                          where pj.Lease_Detail_ID == l.Lease_Detail_ID
                                                                          orderby pj.Payment_Date ascending
                                                                          select pj.Payment_ID).FirstOrDefault()).DefaultIfEmpty()
                             join a in leases.tblfAuthorizations on l.Lease_Detail_ID equals a.Lease_Detail_ID into la
                             from jla in la.Where(x => x.Authorization_ID == (from aj in leases.tblfAuthorizations
                                                                                  where aj.Lease_Detail_ID == l.Lease_Detail_ID
                                                                                  orderby aj.Authorized_Date ascending
                                                                                  select aj.Authorization_ID).FirstOrDefault()).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,
                                 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,
                                 Authorized = jla.Authorized,
                                 Payment_Date = jlp.Payment_Date
                             });