2012-05-03 13 views
1

我有一個嵌套結構。在linq中子查詢而不是遞歸

類頁有ChildPages

class Page 
{ 
IQueryable<Page> ChildPages; 
string type; //catalog or product 
} 

我需要得到我應該得到的所有產品(類型==「產品」)的所有子類別(類型==「目錄」的樣本的請求)

它很容易做循環和遞歸。但它需要大量的時間和資源

+4

您已經使用的話,「網頁」,「ChildPage」,「產品」,「產品目錄」和「子類別」來形容一個關係,所以我承認我很困惑。 –

+2

你的問題需要一點「重構」來使它更清晰。 –

+0

如果沒有遞歸或循環,你無法做到這一點。除此之外,你還可以在任何深度獲得所有後代子頁面? –

回答

1

我不認爲這在EF中受支持,但是您可以使用遞歸CTE查詢在一次數據庫調用中檢索整個樹。

0

我知道這樣做的唯一方法遞歸的LINQ是使用不動點運算符(見下文)

但我懷疑EF將能夠將此轉換爲CTE查詢(見@erikkallen答案),這是我知道在一個語句中執行遞歸查詢的唯一方法。

class Page 
{ 
    IQueryable<Page> ChildPages; 
    string type; //catalog or product 

    // the query 
    static IQueryable<Page> GetProductsWithCatalogAncestor(IQueryable<Page> pages) 
    { 
     return FixPoint<bool, IQueryable<Page>, IQueryable<Page>> 
      (processChildPages => (hasCatalogAncestor, thePages) 
       => thePages.SelectMany(p => (hasCatalogAncestor && p.type == "product") 
        ? new[] { p }.AsQueryable() 
        : processChildPages(hasCatalogAncestor || p.type == "catalog", p.ChildPages))) 
        (false, pages); 
    } 

    // Generic FixPoint operator 
    static Func<T1, T2, TResult> FixPoint<T1, T2, TResult>(Func<Func<T1, T2, TResult>, Func<T1, T2, TResult>> f) 
    { 
     return (t1, t2) => f(FixPoint(f))(t1, t2); 
    } 
} 
-1

嘗試使用SelectMany()來展平層次結構。

var data = pages.SelectMany(p=>p.ChildPages) 
       .Where(p=>p.type == "product" || p.type == "catalog");