【问题标题】:generated SQL Query changes based on different selection in Linq根据 Linq 中的不同选择生成 SQL 查询更改
【发布时间】:2018-01-17 11:05:51
【问题描述】:

我正在将 SQL 查询转换为 LINQ。它有多个内连接、左连接和右连接。我在每一步都检查从 LINQ 生成的 SQL。但问题是基于生成的sql查询更改的选择。

在我的 Linq 下

var a = from freight in billingEntity.FreightCharges.AsNoTracking()
                        join service in billingEntity.ServiceTypes.AsNoTracking()
                        on freight.ServiceTypeId equals service.Id

                        join transport in billingEntity.TransportationTypes.AsNoTracking()
                        on freight.TransportationTypeId equals transport.Id

                        join division in billingEntity.DivisionDetails.AsNoTracking()
                        on freight.OriginId equals division.OriginID

                        join mail in billingEntity.Mailclasses.AsNoTracking()
                        on freight.MailClassId equals mail.MailClassId
                        into mailClassFreight

                        from mail in mailClassFreight.DefaultIfEmpty()
                        join process in billingEntity.ProcessingCategories.AsNoTracking()
                        on freight.ProcessingcategoryId equals process.ProcessingCategoryId
                        into processFreight

                        from processCategory in processFreight.DefaultIfEmpty()
                        select mail;
                string v = a.ToString();

生成的 SQL 为

SELECT 
    [Extent3].[MailClassId] AS [MailClassId], 
    [Extent3].[MailClassName] AS [MailClassName], 
    [Extent3].[CreatedDate] AS [CreatedDate]
    FROM   [dbo].[FreightCharges] AS [Extent1]
    INNER JOIN [dbo].[DivisionDetails] AS [Extent2] ON [Extent1].[OriginId] = [Extent2].[OriginID]
    LEFT OUTER JOIN [dbo].[Mailclass] AS [Extent3] ON [Extent1].[MailClassId] = [Extent3].[MailClassId]
    WHERE ([Extent1].[ServiceTypeId] IS NOT NULL) AND ([Extent1].[TransportationTypeId] IS NOT NULL)

我可以看到 dbo.ProcessingCategory 在连接中丢失。

如果我执行select processCategory,SQL 会生成缺少dbo.MailClass

我尝试转换为 LINQ 的 SQL 查询如下

select * from 
dbo.FreightCharges as fc
inner join dbo.ServiceType as st
on fc.ServiceTypeId = st.Id
inner join dbo.TransportationTypes as tt
on fc.TransportationTypeId = tt.Id
inner join dbo.DivisionDetails as dd
on fc.OriginId = dd.OriginId
left join dbo.Mailclass as mc
on fc.MailClassId = mc.MailClassId
left join dbo.ProcessingCategory as pc
on fc.ProcessingcategoryId = pc.ProcessingCategoryId
right join dbo.ContentTitle as ct
on fc.ContentTitleId = ct.ContentTitleId
inner join dbo.AccountDetails as ac
on ct.AccountId = ac.AccountId
where 
fc.EffectiveThruDate >= '9999-12-31'
or 
fc.EffectiveThruDate is null

【问题讨论】:

  • 所以你想选择每个加入的表的所有列还是只选择FrieghtCharges表?
  • @EhsanSajjad 我需要一些选定的列。但我认为,如果我从所有表中选择列,连接就会正确,MailClassProcessingCategory 会出现正确的连接

标签: c# sql-server linq


【解决方案1】:

您可以像这样将查询联接更改为左联接。

select * from 
dbo.ContentTitle ct
inner join dbo.AccountDetails as ac
    on ct.AccountId = ac.AccountId
left join dbo.FreightCharges as fc
    on fc.ContentTitleId = ct.ContentTitleId and fc.EffectiveThruDate >= '9999-12-31'
left join dbo.ServiceType as st
    on fc.ServiceTypeId = st.Id
left join dbo.TransportationTypes as tt
    on fc.TransportationTypeId = tt.Id
left join dbo.DivisionDetails as dd
    on fc.OriginId = dd.OriginId
left join dbo.Mailclass as mc
    on fc.MailClassId = mc.MailClassId
left join dbo.ProcessingCategory as pc
    on fc.ProcessingcategoryId = pc.ProcessingCategoryId

Linq 等效

from ct in ContentTitles
join ac in AccountDetails on ct.AccountId equals ac.AccountId 
join fc in FreightCharges on ct.ContentTitleId equals fc.ContentTitleId into lfc
from flfc in lfc.Where(f => f.EffectiveThruDate >= new DateTime(9999,12,31)).DefaultIfEmpty()   
join st in ServiceTypes on flfc.ServiceTypeId equals st.Id into lst
from flst in lst.DefaultIfEmpty()   
join tt in TransportationTypes on flfc.TransportationTypeId equals tt.Id into ltt
from fltt in ltt.DefaultIfEmpty()   
join dd in DivisionDetails on flfc.OriginId equals dd.OriginId into ldd
from fldd in ldd.DefaultIfEmpty()   
join mc in Mailclasses on flfc.MailClassId equals mc.MailClassId into lmc
from flmc in lst.DefaultIfEmpty()   
join pc in ProcessingCategories on flfc.ProcessingcategoryId equals pc.ProcessingCategoryId into lpc
from flpc in lst.DefaultIfEmpty()   
select new {ct, ac, lfc, lst ,ltt, ldd, lmc, lpc}

【讨论】:

    猜你喜欢
    • 2015-06-11
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多