2017-04-13 76 views
1

我遇到將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

回答

2

當涉及到連接的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

4

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

相關問題