2008-09-04 64 views
5

我有一個自引用Categories表。每個類別都有一個CategoryID,ParentCategoryID,CategoryName等。每個類別可以有任意數量的子類別,每個子類別可以有任意數量的子類別,等等。所以基本上這棵樹可以是X級的。用於自引用表的LINQ to SQL?

然後產品與葉(子)類相關聯。有沒有一種方法可以使用LINQ to SQL來獲取任何給定類別的所有產品(這將是所有與葉子後代相關的產品)?

這感覺就像一個遞歸問題。使用存儲過程是否更好?

回答

3

我不認爲linq-to-sql對這個問題有很好的答案。由於您使用的是SQL Server 2005,因此您可以使用CTE進行分層查詢。存儲過程或內聯查詢(使用DataContext.ExecuteQuery)都可以實現。

1

那麼這裏是一個使用LINQ的可怕的匆忙實施。 不要使用此:-)

public IQueryable GetCategories(Category parent) 
{ 
    var cats = (parent.Categories); 
    foreach (Category c in cats) 
    { 
     cats = cats .Concat(GetCategories(c)); 
    } 
    return a; 
} 
1

的高性能方法是創建一個插入/修改/刪除觸發器,它維護着一個包含所有節點的所有祖先節點的祖先對一個完全不同的表。這樣,查找是O(N)。

要使用它獲取屬於節點及其所有後代的所有產品,只需選擇以目標節點爲祖先的所有類別節點即可。在此之後,您只需選擇屬於任何這些類別的任何產品。

1

我處理這個問題的方式是使用一些擴展方法(過濾器)。我已經寫了一個我已經實現了這個項目的示例代碼。特別注意我填充ParentPartner對象和SubPartners列表的行。

public IQueryable<Partner> GetPartners() 
     { 
      return from p in db.Partners 
        select new Partner 
        { 
         PartnerId = p.PartnerId, 
         CompanyName = p.CompanyName, 
         Address1 = p.Address1, 
         Address2 = p.Address2, 
         Website = p.Website, 
         City = p.City, 
         State = p.State, 
         County = p.County, 
         Country = p.Country, 
         Zip = p.Zip, 
         ParentPartner = GetPartners().WithPartnerId(p.ParentPartnerId).ToList().SingleOrDefault(), 
         SubPartners = GetPartners().WithParentPartnerId(p.PartnerId).ToList() 
        }; 
     } 


public static IQueryable<Partner> WithPartnerId(this IQueryable<Partner> qry, int? partnerId) 
     { 
      return from t in qry 
        where t.PartnerId == partnerId 
        select t; 
     } 

public static IQueryable<Partner> WithParentPartnerId(this IQueryable<Partner> qry, int? parentPartnerId) 
     { 
      return from p in qry 
        where p.ParentPartner.PartnerId == parentPartnerId 
        select p; 
     } 
+0

我認爲這是一個好主意,但是我試圖實現這個時遇到錯誤。它說「WithPartnerId」擴展方法沒有支持到SQL的轉換。有任何想法嗎? – 2009-03-09 20:29:45