2009-10-16 136 views
0

是否有可能使用linqtosql來完成這樣的事情?LinqToSql中的多個左外連接?

select * from table t1 
left outer join table2 t2 on t2.foreignKeyID=t1.id 
left outer join table3 t3 on t3.foreignKeyID=t1.id 

我可以使用DataLoad選項或聯接語法使其工作。但問題是,無論何時添加第二個左連接,linqtosql使用MULTIPLE sql語句進行查詢,而不是在底層sql中執行第二次左連接。

因此,像上面這樣的查詢將導致數十個SQL調用,而不是一個SQL調用與2個左連接。

我的其他選擇是什麼?我可以在數據庫中使用視圖,但現在我負責從平展列表創建層次結構,這是首先使用ORM的原因之一。

請注意,T2和T3與T1是1:M的關係。是否有可能讓linq有效地查詢這些並返回層次結構?

+0

,你能否告訴我們您正在使用LINQ語法? – 2009-10-16 19:34:53

回答

1

我不認爲這是有可能是正確的解決您的問題,因爲有一個以上的多對一關係到父實體表:

select * from table t1 
left outer join table2 t2 on t2.foreignKeyID = t1.id 
left outer join table3 t3 on t3.foreignKeyID = t1.id 

這就像有多個孩子,多輛車的人:

說T1是人

id    str 
1    Me 

說T2是孩子

PK foreignKeyID str 
A 1    Boy 
B 1    Girl 

說T3是車輛

PK foreignKeyID str 
A 1    Ferrari 
B 1    Porsche 

你的結果集爲:

Me Boy Ferrari 
Me Girl Ferrari 
Me Boy Porsche 
Me Girl Porcshe 

哪我無法看到這是一個有用的查詢(即使在SQL中)。

+0

雅,你可能是對的。我想我要完成的是沒有多次命中數據庫的父實體的深度加載。我有一個觀點,目前返回你描述的結果,只是希望我可以讓linq爲我創建層次結構。但我認爲這是一廂情願的想法。 請參閱當您進入更復雜的結果集時,我無法看到Linq語法如何有益。在我看來,這比將sql放在視圖中更難理解。唯一的好處是,如果linq可以神奇地構建等級。缺席,我將恢復到SQL視圖。 – Scott 2009-10-16 19:49:10

+0

我不是一個沉重的LINQ2SQL用戶。對於深層次的對象層次結構,我們使用存儲過程返回多個記錄集,然後使用NextRecordset來填充實體對象的子集合(當然,除非延遲加載)。如果你正在嘗試魔術,你可能想看看ORM。 – 2009-10-16 19:52:07

+1

謝謝凱德,那也是我的想法。我認爲sprocs可以解決一些問題。但是,我可以使用Linq完成類似的事情。只抓取根實體。然後在第二個查詢中加入我想要的孩子。在第三個查詢中加入其他孩子。然後把它放在記憶中。 這樣,我減少了DB調用3,並仍然獲得linq的所有優勢。 目前的方法最終爲每個孩子查詢DB一次。因此,在一個包含100條記錄的頁面中,您只需加載100個查詢來加載第二個孩子集合,而不是3. Sprocs = 1查詢,但是然後我失去了線索:) – Scott 2009-10-16 19:58:57

1

Here is a similar question。瞭解聯結是如何組成的。

例如,以下LINQ到SQL查詢上的AdventureWorks:

AdventureWorksDataContext db = new AdventureWorksDataContext(); 

var productStuff = from p in db.Products 
        join pl in db.ProductListPriceHistories on p.ProductID equals pl.ProductID into plv 
        from x in plv.DefaultIfEmpty() 
        join pi in db.ProductInventories on p.ProductID equals pi.ProductID into pii 
        from y in pii.DefaultIfEmpty() 
        where p.ProductID == 764 
        select new { p.ProductID, x.StartDate, x.EndDate, x.ListPrice, y.LocationID, y.Quantity }; 

,得到相同的SQL(通過探查驗證),因爲這SQL查詢:

SELECT Production.Product.ProductID, 
     Production.ProductListPriceHistory.StartDate, 
     Production.ProductListPriceHistory.EndDate, 
     Production.ProductListPriceHistory.ListPrice, 
     Production.ProductInventory.LocationID, 
     Production.ProductInventory.Quantity 
FROM Production.Product 
LEFT OUTER JOIN Production.ProductListPriceHistory ON Production.Product.ProductID = Production.ProductListPriceHistory.ProductID 
LEFT OUTER JOIN Production.ProductInventory ON Production.Product.ProductID = Production.ProductInventory.ProductID 
WHERE Production.Product.ProductID = 764 

多LEFT JOIN的上主父表的鍵,產生一個生成的SQL查詢。

+0

這不適用。 請注意,我的左連接都加入到相同的父表(T1)。我不想將T2連接到T3,並返回T1,T2和T3的結果。 T1與幾個表具有1:M關係。 我試圖通過多個左連接返回T1的孩子,而不會引發每個父元素對所有左連接後的第一個SQL調用。 – Scott 2009-10-16 19:23:35

0

我想的LINQ to SQL將能夠只要你把DefaultIfEmpty(翻譯你的左外連接)調用在正確的地方:

var q = from t1 in table 
     join t2 in table2 on t1.id equals t2.foreignKeyID into j2 
     from t2 in j2.DefaultIfEmpty() 
     join t3 in table3 on t1.id equals t3.foreignKeyID into j3 
     from t3 in j3.DefaultIfEmpty() 
     select new { t1, t2, t3 }; 
+0

是的,它可以翻譯。但如果我加入多個表格,它會將其轉換爲數十個SQL調用。 – Scott 2009-10-16 19:27:28

0

如果您的FK設置正確,您不需要可怕的連接語法。

你可能會寫:

var q = from t1 in dc.table1s 
     from t2 in t1.table2s.DefaultIfEmpty() 
     from t3 in t1.table3s.DefaultIfEmpty() 
     select new { t1, t2, t3 };