2012-05-03 14 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");