Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# sql到linq的多个连接条件_C#_Linq - Fatal编程技术网

C# sql到linq的多个连接条件

C# sql到linq的多个连接条件,c#,linq,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.

如何将下面的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上的db.TbleC中加入c{ w=(int?)c.addrid,z=c.userid}

我确实知道问题出在哪里,我正在比较联接中的两个表。 谢谢,错误是:

join子句中某个表达式的类型不正确“”调用join时类型推断失败


我怀疑您的错误是由于试图比较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)

我怀疑您的错误是由于试图比较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)

在不知道所涉及的类型的情况下,我们无法真正判断当前查询在编译方面有什么问题,但它无论如何都不会等同于原始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与空条件运算符一起使用。如果不是,您至少在逻辑上需要:


在不知道所涉及的类型的情况下,我们无法真正判断当前查询在编译方面有什么问题,但它无论如何都不会等同于原始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与空条件运算符一起使用。如果不是,您至少在逻辑上需要:



请确切说明错误是什么-当我们看不到问题时,很难提供帮助。您的sql查询不清楚:如果您在
TbleB
上使用
Where
子句,就好像您在进行内部连接一样。您想要左连接还是内连接?顺便问一下,为什么必须强制转换为
int?
b.addrid和c.addrid不是同一类型?@JonSkeet它说连接的类型不正确,我想我还提到了错误所在。如果你仔细看看我的linq,我知道问题出在哪里。请参阅我的更新。@RaphaëlAlthaus我强制转换为接受空值,这在linq中是正确的。那么什么是linq中的内部连接呢?对,所以在将来,正确的做法是在问题中包含完整的错误消息。我建议您在中编辑它,以及我询问过的其他信息……请确切说明错误是什么-当我们看不到问题时,很难提供帮助。您的sql查询不清楚:如果您在
TbleB
上左加入
,并在
TbleB
上使用
Where
子句,就好像你在做一个内部连接。您想要左连接还是内连接?顺便问一下,为什么必须强制转换为
int?
b.addrid和c.addrid不是同一类型?@JonSkeet它说连接的类型不正确,我想我还提到了错误所在。如果你仔细看看我的linq,我知道问题出在哪里。请参阅我的更新。@RaphaëlAlthaus我强制转换为接受空值,这在linq中是正确的。那么什么是linq中的内部连接呢?对,所以在将来,正确的做法是在问题中包含完整的错误消息。我建议您在中编辑它,以及我询问过的其他信息…在联接中使用匿名类型是绝对好的。我的错。有点太快了。我只将其用于
let
select
,无法想象它们可以用于equals。但这仍然不等同于原始查询。这起作用并消除了错误,所以我添加了int?对于这两个比较,我建议您看看正在生成的SQL—我强烈怀疑它不会是您想要的,因为它不是左外部联接。在联接中使用匿名类型是完全可以的。我的错。有点太快了。我只将其用于
let
select
,无法想象它们可以用于equals。但这仍然不等同于原始查询。这起作用并消除了错误,所以我添加了int?对于这两个比较,我建议您查看正在生成的SQL—我强烈怀疑它不会是您想要的,因为它不是一个左外连接。@RaphaëlAlthaus:很好的捕获-添加了。@JonSkeet我得到这个错误是因为“转换为值类型'System.Int32'失败,因为具体化的值为null。结果类型的泛型参数或查询必须使用可为空的类型。“@Menew:不幸的是,很难从远程准确诊断出问题所在。我建议您尝试将此问题简化为一个绝对最小的查询来演示问题,然后再问一个新问题-尽管我怀疑在将其简化为最小查询的过程中,您将能够解决问题。@RaphaëlAlthaus:Good catch-added.@Jonsket我得到这个错误是因为“转换为值类型'System.Int32'失败,因为具体化的值为null。结果类型的泛型参数或查询必须使用可为空的类型。“@Menew:不幸的是,很难从远程准确诊断出问题所在。我建议您尝试将其简化为一个绝对最小的查询来演示问题,然后提出一个新问题-尽管我怀疑在将其简化为最小查询的过程中,您将能够解决问题。