2008-09-04 6 views
5

私は自己参照カテゴリテーブルを持っています。各カテゴリには、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への変換がサポートされていないと言われています。何か案は? –