在MS SQL 2005和最多可以創建遞歸查詢。但是,在LINQ to SQL中,你運氣不佳。如果不重構數據庫中的數據,則無法在單個數據庫調用中遍歷樹。
但是...有1個解決方法我能想到的。如果能夠將單個樹(或樹的一部分)的所有Category
元素分組在一起,則可以在單個語句中預加載完整樹的該部分。之後,您將能夠遍歷該樹的該部分,而不會觸發對數據庫的新調用。它看起來像這樣:
// Load the category that will be used as starting point.
var subCategory = db.Categories.Single(c => c.Id == 56);
// Performance: Load the complete group in one go.
var categories = (
from category in db.Categories
where category.GroupId == subCategory.GroupId
select category)
.ToArray();
// Traverse the tree and get the top-most parent (if any).
var parent = subCategory.GetParents().LastOrDefault();
// Extension method to get the parents.
public static IEnumerable<Category> GetParents(
this Category category)
{
while (category.Parent != null)
{
// NOTE: cat.Parent will not cause a database call
// when the Parent is already loaded by L2S.
yield return cat.Parent;
category = category.Parent;
}
}
這當然只有在你能夠確定元素爲一個組時纔有用。這個解決方案是否會更快取決於組的大小。當您加載(並且不使用)的對象組非常大時,它實際上會減慢應用程序的速度。