【问题标题】:Implement left outer join using EF使用 EF 实现左外连接
【发布时间】:2016-08-19 17:08:48
【问题描述】:

我正在尝试在 VS2015 中使用 c# 将 sql 语句转换为 EF

下面是SQL语句:

Select i.cdin_cdindexid,p.pinv_PerformaInvID,coalesce(i.cdin_serial,0) as depno 
                         ,coalesce(convert(datetime,left(convert(nvarchar,i.cdin_startunstufdate,120),10),120),'-') as deidate,coalesce(i.cdin_goodsDesc,'-') as gooddesc ,coalesce(i.cdin_Customdeclar,'-') as custdec 
                         ,coalesce(i.cdin_NoofPackages,0) as pkg,coalesce(i.cdin_WT,0) as wt ,coalesce(i.cdin_volumewt,0) as vwt ,coalesce(i.cdin_MortgageAmount,0) as lcamt,coalesce(p.pinv_name,'-') as invno,coalesce(p.pinv_TotalAmount,0) as invamt,p.pinv_Status,p.pinv_InvoiceProperty as prop 
                         ,coalesce(c.comp_name,'-') as custname,coalesce(Comp_CompanyId,'-') as custid ,coalesce(c.comp_idcust,'-') as accpacno,coalesce(t.Terr_Caption,'-') as Terr,convert(nvarchar,'01',2) as type     
                         from cdindex i inner join   company c on i.cdin_CompanyId =c.Comp_CompanyId  inner join Territories t on i.cdin_Secterr =t.Terr_TerritoryID left outer join PerformaInv p on i.cdin_cdindexid=p.pinv_CDIndexId 
                         where(cdin_deleted Is null And c.comp_deleted Is null And t.Terr_Deleted Is null And p.pinv_deleted Is null)
                         and cdin_startunstufdate between '2016-06-01' and '2016-07-28'
                          and (p.pinv_status in('Draft','Posted') or pinv_status is null) and (p.pinv_InvoiceProperty ='01' or p.pinv_InvoiceProperty is null )

我试图实现连接,但我被困在如何使用 into 和 DefaultIfEmpty() 对 PerformaInv 表进行左外连接,然后 on i.cdin_cdindexid=p.pinv_CDIndexId

这是我尝试的:

ar q = (from i in db.CDIndexes
             join c in db.Companies on i.cdin_CompanyId equals c.Comp_CompanyId
             join t in db.Territories on i.cdin_Secterr equals t.Terr_TerritoryID into
              p from pr in p.DefaultIfEmpty

             where (i.cdin_startunstufdate>= new DateTime(2016 - 06 - 01) && i.cdin_startunstufdate>= new DateTime(2016-06-28)

             )



             select new
             {

                 i.cdin_CDIndexID,
                 i.cdin_Serial,
                 i.cdin_startunstufdate,
                 i.cdin_goodsDesc,
                 i.cdin_Customdeclar,
                 i.cdin_NoofPackages,
                 i.cdin_WT,
                 i.cdin_volumewt,
                 i.cdin_MortgageAmount,

             });

我知道缺少很多东西,但我真的很糟糕。

【问题讨论】:

  • 先用内连接,再转成左外连接,就是加一行。此外,如果您在模型中创建导航属性,则根本不需要编写连接。
  • @IvanStoev 这是做什么的:from i in db.CDIndexes join c in db.Companies on i.cdin_CompanyId equals c.Comp_CompanyId join t in db.Territories on i.cdin_Secterr equals t.Terr_TerritoryID join p in db.PerformaInvs on i.cdin_CDIndexID equals p.pinv_CDIndexId
  • @IvanStoev 对不起,Ivan 先生,我该如何导航?就像在这个link 中一样,请你解释一下在不使用连接的情况下实现代码的方法。
  • 是的,就像那个链接一样。没有“实体”类很难解释,但想法是,如果你有两个类 A 和 B 以及一对多关系,你输入 A public ICollection<B> Bs P { get; set; } 和 B public A A { get; set; } 和然后在查询中,您可以使用a.Bsb.A,EF 将为您连接 A 和 B 表。
  • @IvanStoev 不幸的是,我不明白你在说什么,嗯,我猜想将 ORM 与普通 SQL 语句一起使用是使用连接或复杂 SQL 语句的最佳解决方案。

标签: c# sql sql-server entity-framework linq


【解决方案1】:

正如我在 cmets 中提到的,最好使用导航属性。但是,一旦您开始使用手动连接,将内连接转为左外连接(虽然不是自然的)就不是那么难了。

鉴于你的加入

from i in db.CDIndexes
join c in db.Companies on i.cdin_CompanyId equals c.Comp_CompanyId
join t in db.Territories on i.cdin_Secterr equals t.Terr_TerritoryID
join p in db.PerformaInvs on i.cdin_CDIndexID equals p.pinv_CDIndexId
...

您可以使用join clause (C# Reference) - Left Outer Join 中显示的模式将其中任何一个转换为左外连接

from i in db.CDIndexes
join c in db.Companies on i.cdin_CompanyId equals c.Comp_CompanyId
join t in db.Territories on i.cdin_Secterr equals t.Terr_TerritoryID
join p in db.PerformaInvs on i.cdin_CDIndexID equals p.pinv_CDIndexId
// the following line turns the above join to left outer
into p_Join from p in p_Join.DefaultIfEmpty()
...

【讨论】:

  • 太棒了,非常感谢,我想根据原始 SQL 语句对其进行测试,但我还有一个问题,请问如何在 where 子句中实现 (Is Null) 以完成此 where in LINQ:` where (i.cdin_startunstufdate >= new DateTime(2016 - 06 - 01) && i.cdin_startunstufdate >= new DateTime(2016 - 06 - 28) && p.pinv_Status == "草稿" || p.pinv_Status == "已发布" && p.pinv_InvoiceProperty == "01" ) `
  • SQL Is Null => LINQ == null
  • 我从 2 小时开始尝试实现它,但结果是生成的查询与 SQL Server 中的不同。
  • 你知道 SO 规则。每个帖子只有一个问题,一旦得到回答,就没有“更新”/“附加”问题。我认为以上内容涵盖了 Implement left outer join using EF 问题,如果您有其他要求,请发布另一个问题。对于这个,你可以接受答案,发布你自己的答案或删除帖子(如果你想做最后一个,请告诉我,所以我删除答案以便你这样做)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-25
  • 2016-02-21
  • 1970-01-01
  • 2011-10-01
  • 1970-01-01
相关资源
最近更新 更多