2010-10-06 54 views
0

我有以下表,的MenuItems,在數據庫中:如何在Linq2Sql中做遞歸查詢?

ID ParentID Name 
--- --------- ----- 
1 0   Item 1 
2 1   Item 2 
3 1   Item 3 
4 0   Item 4 
5 3   Item 5 

我想寫一個擴展方法來獲得所有菜單項樹的根。事情是這樣的:

public IQueryable<MenuItem> GetToRoot(this IQueryable<MenuItem> source, int menuItemID) 
{ 
    return from m in source 
      ???? 
      ???? 
      select m; 
} 

如果我把上面的ID爲3的菜單項的數據這種擴展方法,我應該得到:

ID ParentID Name 
--- --------- ----- 
1 0   Item 1 
3 1   Item 3 

這可能與LINQ2SQL只有一個呼叫數據庫?

回答

1

我不認爲你可以在單個查詢中做到這一點,這是我的想法:發現一個項目的父項有效地需要表與它自己的一個連接。每個附加的菜單級別都需要表格與其自身的更多聯接。您需要多少聯接/附加層才能達到根?你不會知道,直到你執行每一個,對吧?因此,無論是在數據庫/ SQL方面,還是在LINQ to SQL方面,您都必須一次完成每一步。

如果你知道你的菜單系統不會超出一定的深度,我想你可以設置一個LINQ to SQL查詢,這個查詢將自己連接到該表的次數,但這聽起來很醜。

我建議在你的DBML設計器中建立一個表與它自己的關聯,這會給你一個父類EntityRef<>這個類的屬性。由於您的LoadOptions中不允許循環(因此無法預先加載父級),所以您可以在實體的部分OnLoaded()方法中強制執行父級的延遲加載。

這裏有一些相關的SO問題:

https://stackoverflow.com/questions/1435229/hierarchy-problem-replace-recursion-with-linq-join LINQ to SQL for self-referencing tables?

這是問題的一個服務器端/ SQL處理:

http://www.sqlteam.com/article/more-trees-hierarchies-in-sql

這裏是誰寫的我的幫手代碼:

http://www.scip.be/index.php?Page=ArticlesNET18