【问题标题】:LINQ query with sub-query on LEFT JOIN conditions带有 LEFT JOIN 条件子查询的 LINQ 查询
【发布时间】:2015-12-07 16:58:28
【问题描述】:

我在 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: (在几个 cmets 后编辑)

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] )))

问题在于,一旦支付和授权连接具有完全相同的结构,它只会更加混乱。

【问题讨论】:

  • 这可能是 linq 查询上的不同操作吗?这是我的猜测,因为它返回的行数较少。
  • 刚刚尝试删除它,它仍然检索相同。无论如何,感谢您提供帮助!
  • 我认为 SQL Server 默认按升序排序,所以这是我看到的一个区别。在 SQL 中,子查询按升序执行,但 LINQ 显式降序执行。如果您还没有这样做,可以尝试一下。
  • 观察得好,山姆!它没有解决问题,但肯定使查询更好。非常感谢!
  • Authorized 和 Payment 子查询的顺序无关紧要。

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


【解决方案1】:

经过一番研究,我终于找到了方法。这是生成我试图获取的 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
                             });

【讨论】:

  • 您可以通过解释您的基本更改来使这对未来的读者有用。此外,最好只显示更改的行。
  • 基本上我改变的是与子查询的连接,Gert
猜你喜欢
  • 1970-01-01
  • 2014-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-31
  • 2021-01-28
  • 2013-05-13
  • 1970-01-01
相关资源
最近更新 更多