将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'

有什么建议吗?

+5

最好的建议是 - 没有。 LINQ只是一种查询语言。 *实体框架*另一方面是* ORM *。它将* objects *映射到表格。使用关系和导航属性创建适当的*实体*,EF将生成JOIN语句。 –

+1

假设您的实体是Order和LineItem,每个LineItem都可以有一个Order属性。订单应该有一个'LineItems'集合。如果您想加载订单和所有订单项,则只需加载订单即可。它的LineItems将会加载它 –

+1

这个'从table 1 table1'看起来不正确。 “从表1中的表1'都没有。这样的名称中不能有空格。另外'table2.Column2 = 1838'应该是真正的原因,而不是sql中连接的on子句,并且绝对不能在Linq连接中存在。 – juharr

当涉及到连接的on子句时,Linq比SQL更严格。基本上它将equals一侧的东西与另一侧进行比较。 equals==不同,您不能将更多逻辑链接到逻辑运算符的末尾。最好的方法是将构成表之间关系的列放入连接的on子句中。

join table2 in table_2 on table1.Column1 equals table2.Column1 into result 

然后移动table2.Column2 == 1838where

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() 
.... 
+0

感谢@juharr的解释和纠正。所以有了这样的想法,即在联合声明中只允许有一个等号。我会尝试将它移到where子句,看看我能否得到相同的结果。同样感谢您对EF的建议,我会研究这一点。 – Kevin

+0

虽然有一个问题,为什么我们不需要将表格引用名称放在第二列'on new {table1.Column1,Column2 = 1838}'这一行? – Kevin

+1

@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 
+0

嗯...是一个“深层平等”还是仅仅是一个参照等于? –

+1

@RobertHarvey C#anonoymous类型具有值比较语义。按组合键使用相同的技术,所以显然如果它是引用相等,它将不起作用。 –

+1

@RobertHarvey另外在这种情况下,它可能会变成SQL。 – juharr