将SQL查询转换为LINQ - 操作符'&&'不能应用于'int'和'bool'类型的操作数
我遇到将SQL查询转换为LINQ的问题。我觉得我有这95%复制到LINQ但是其问题上加入将SQL查询转换为LINQ - 操作符'&&'不能应用于'int'和'bool'类型的操作数
SQL
SELECT
table1.Column1
FROM
table 1 table1
LEFT OUTER JOIN
table 2 table2 ON table2.Column1 = table1.Column1
AND table2.Column2 = 1838
WHERE
table1.Column2 = 1
AND table1.Column3 = 24029
AND (table2.[Column3] IS NULL OR table2.[Column3] = 1)
LINQ到目前为止
var query = from table1 in table 1
join table2 in table 2 on table1.Column1 equals table2.Column1 && table2.Column2 == 1838 into result
from table2 in result.DefaultIfEmpty()
where table1.Column2 == 1 && table1.Column3 == 24029 && (table2.Column3 == null || table2.Column3 == 1)
select table1.Column1;
当我运行查询我在此得到一个错误线
join table2 in table 2 on table1.Column1 equals table2.Column1 && tabl2.Column2 == 1838 into result
错误:
CS0019 Operator '&&' cannot be applied to operands of type 'int' and 'bool'
有什么建议吗?
当涉及到连接的on子句时,Linq比SQL更严格。基本上它将equals
一侧的东西与另一侧进行比较。 equals
与==
不同,您不能将更多逻辑链接到逻辑运算符的末尾。最好的方法是将构成表之间关系的列放入连接的on子句中。
join table2 in table_2 on table1.Column1 equals table2.Column1 into result
然后移动table2.Column2 == 1838
到where
where table2.Column2 == 1838
&& table1.Column2 == 1
&& table1.Column3 == 24029
&& (table2.Column3 == null || table2.Column3 == 1)
另外,这也将工作,但确实不是最好的做法。
join table2 in table_2
on new {table1.Column1, Column2 = 1838}
equals new {table2.Column1, table2.Column2 } into result
由于这是你怎么做多重比较,但要注意它只会做与SQL平等的,它会让你做任何类型的逻辑条款。
另外,如果你使用EF和表有你应该有导航性能外键关系,你可以这样做
from table1 in table_1
from table2 in table1.table_2s.DefaultIfEmpty()
....
感谢@juharr的解释和纠正。所以有了这样的想法,即在联合声明中只允许有一个等号。我会尝试将它移到where子句,看看我能否得到相同的结果。同样感谢您对EF的建议,我会研究这一点。 – Kevin
虽然有一个问题,为什么我们不需要将表格引用名称放在第二列'on new {table1.Column1,Column2 = 1838}'这一行? – Kevin
@Kevin在这种情况下,我们创建一个匿名类,第二个属性的值是1838,名称是“Column2”,因此它将匹配另一个匿名类。基本上,如果你引用一个匿名类中的属性,它将采用该属性名称,但对于常量值,你必须命名该属性。所以另一种写法是'new {Column1 = table1.Column1,Column2 = 1838} 等于new {Column1 = table2.Column1,Column2 = table2.Column2}' – juharr
为composite key join的LINQ语法是不同的。因此,而不是不正确
join table2 in table_2 on table1.Column1 equals table2.Column1 && table2.Column2 == 1838 into result
,你可以使用类似这样
join table2 in table_2
on new { table1.Column1, Column2 = 1838 } equals new { table2.Column1, table2.Column2 }
into result
嗯...是一个“深层平等”还是仅仅是一个参照等于? –
@RobertHarvey C#anonoymous类型具有值比较语义。按组合键使用相同的技术,所以显然如果它是引用相等,它将不起作用。 –
@RobertHarvey另外在这种情况下,它可能会变成SQL。 – juharr
最好的建议是 - 没有。 LINQ只是一种查询语言。 *实体框架*另一方面是* ORM *。它将* objects *映射到表格。使用关系和导航属性创建适当的*实体*,EF将生成JOIN语句。 –
假设您的实体是Order和LineItem,每个LineItem都可以有一个Order属性。订单应该有一个'LineItems'集合。如果您想加载订单和所有订单项,则只需加载订单即可。它的LineItems将会加载它 –
这个'从table 1 table1'看起来不正确。 “从表1中的表1'都没有。这样的名称中不能有空格。另外'table2.Column2 = 1838'应该是真正的原因,而不是sql中连接的on子句,并且绝对不能在Linq连接中存在。 – juharr