私はネストされた構造を持っています。
クラス ページには ChildPages があります
class Page
{
IQueryable<Page> ChildPages;
string type; //catalog or product
}
すべてのサブカテゴリ(type=="catalog")のすべての製品(type=="product")のサンプルのリクエストを取得する必要があります。
ループと再帰を使えば簡単です。しかし、それには多くの時間とリソースが必要です
私はネストされた構造を持っています。
クラス ページには ChildPages があります
class Page
{
IQueryable<Page> ChildPages;
string type; //catalog or product
}
すべてのサブカテゴリ(type=="catalog")のすべての製品(type=="product")のサンプルのリクエストを取得する必要があります。
ループと再帰を使えば簡単です。しかし、それには多くの時間とリソースが必要です
EF ではサポートされていないと思いますが、再帰的な CTE クエリを使用して、1 回のデータベース呼び出しでツリー全体を取得できます。
私が知っている再帰的な Linq の唯一の方法は、Fixpoint 演算子を使用することです (以下を参照)。
しかし、EF がこれを CTE クエリに変換できるとは思えません (@erikkallen の回答を参照)。これは、1 つのステートメントで再帰クエリを実行する唯一の方法です。
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);
}
}
SelectMany()
を使用して階層をフラット化してみてください。
var data = pages.SelectMany(p=>p.ChildPages)
.Where(p=>p.type == "product" || p.type == "catalog");