多条连接条件sql到linq

时间:2016-04-08 14:28:10

标签: c# linq

如何将下面的sql更改为linq。

select distinct * from dbo.TbleA a
left outer join dbo.TbleB b on a.schid = b.schid
left outer join dbo.TbleC c on b.addrid=c.addrid
and c.userid=a.userid
where b.addrid=1 

这是我的linq版本导致错误:

from a in db.TbleA
join b in db.TbleB on a.schid equals b.schid
join c in db.TbleC on new { w = b.addrid, z = a.userid } equals new { w=(int?)c.addrid, z=c.userid}
where (b.addrid == 1)

我在这里遇到错误:

  

在新的{w = b.addrid,z = a.userid}等于new {{   w =(int?)c.addrid,z = c.userid}

我确实理解问题出在哪里我与我的联盟中的两个表进行比较。 谢谢,错误是:

  

" join子句中某个表达式的类型不正确""在加入调用中类型推断失败"

b.addrid - int, 
a.userid - string, 
c.addrid - int?
c.userid - string

2 个答案:

答案 0 :(得分:2)

我们无法在不知道所涉及的类型的情况下,在编译方面真正说出您当前查询的错误,但它无论如何都不会等同于原始SQL,因为您想要离开外连接。我怀疑你想要更像的东西:

from a in db.TbleA
join b in db.TbleB on a.schid equals b.schid into bs
from b in bs.DefaultIfEmpty()
join c in db.TbleC on new { w = (int?)b?.addrid, z = a.userid }
               equals new { w = c.addrid, z = c.userid } into cs
from c in cs.DefaultIfEmpty()
where (b.addrid == 1)

如果你可以将C#6与null条件运算符一起使用,那当然。如果没有,您至少逻辑上需要:

from a in db.TbleA
join b in db.TbleB on a.schid equals b.schid into bs
from b in bs.DefaultIfEmpty()
join c in db.TbleC on new { w = (b == null ? default(int?) : (int?)b.addrid), z = a.userid }
               equals new { w = c.addrid, z = c.userid } into cs
from c in cs.DefaultIfEmpty()
where b == null || b.addrid == 1

答案 1 :(得分:0)

我怀疑您的错误是由于尝试比较LinQ语句中不同类型的匿名类而引起的。我建议你将联接更改为以下内容:

from a in db.TbleA
join b in db.TbleB on a.schid equals b.schid
join c in db.TbleC on new { w = (int?)b.addrid, z = a.userid } equals new { w=(int?)c.addrid, z=c.userid}
where (b.addrid == 1)