5

自己参照カテゴリ テーブルがあります。各カテゴリには、CategoryID、ParentCategoryID、CategoryName などがあります。また、各カテゴリには任意の数のサブカテゴリを含めることができ、それらの各サブカテゴリには任意の数のサブカテゴリを含めることができます。したがって、基本的にツリーは X レベルの深さになる可能性があります。

次に、製品がリーフ (サブ) カテゴリに関連付けられます。LINQ to SQL を使用して、特定のカテゴリ (すべてのリーフの子孫に関連付けられているすべての製品) のすべての製品を取得する方法はありますか?

これは再帰的な問題のように感じます。代わりにストアド プロシージャを使用した方がよいでしょうか。

4

4 に答える 4

3

linq-to-sqlがこの問題に対する良い答えを持っているとは思いません。SQL Server 2005を使用しているため、CTEを使用して階層クエリを実行できます。ストアドプロシージャまたはインラインクエリ(DataContext.ExecuteQueryを使用)のいずれかでうまくいきます。

于 2008-09-04T06:42:52.107 に答える
2

さて、これはLINQを使用したひどい急いでの実装です。これを使用しないでください:-)

public IQueryable GetCategories(Category parent)
{
    var cats = (parent.Categories);
    foreach (Category c in cats )
    {
        cats  = cats .Concat(GetCategories(c));
    }
    return a;
}
于 2008-09-04T03:05:36.730 に答える
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;
        }
于 2009-01-05T15:56:28.777 に答える
1

パフォーマンスの高いアプローチは、すべてのノードのすべての祖先のノードと祖先のペアを含むまったく異なるテーブルを維持する挿入/変更/削除トリガーを作成することです。このように、ルックアップは O(N) です。

ノードに属するすべての製品とそのすべての子孫を取得するために使用するには、ターゲット ノードを先祖として持つすべてのカテゴリ ノードを選択するだけです。この後、これらのカテゴリのいずれかに属する製品を選択するだけです。

于 2008-09-04T04:06:09.877 に答える