2009-03-23 24 views
1

私はツリー構造を持ったテーブルを持っています。linqでツリー構造のテーブルデータを取得するには?

Id ParentId Name 
---------------- 
1 null x 
2 null y 
3 null z 
4 null t 
5  1  xx 
6  1  xy 
7  1  xz 
8  2  yx 
9  2  yy 
10 9  yyx 
11 10 yyxx 
12 11 yyxxx 

ルートノードの下にあるサブツリー全体を取得します。ルートノードが「x」のとき、ノード{1、5、6、7、10、11、12}のセットを取得したいとします。私はどのようにlinqによってそれを行うことができますか?

答えて

1

テーブル構造を変更して余分なフィールドを追加できる場合は、これまで使用してきたアプローチの1つとして、カンマで区切られたIDのリストを保持する「パス」フィールドがあります。

ID ParentID Name  Path 
-- -------- ----  ---- 
1  null  x   1 
2  null  y   2 
3  null  z   3 
4  null  t   4 
5  1   xx  1,5 
6  1   xy  1,6 
7  1   xz  1,7 
8  2   yx  2,8 
9  2   yy  2,9 
10 9   yyx  2,9,10 
11 10   yyxx  2,9,10,11 
12 11   yyxxx  2,9,10,11,12 

次に、あなたが(またはSTARTSWITH LINQの中)LIKEを使用してパスフィールドに基づいて照会することができ、あなたが取得したいと言うあなたの質問に

{1、5、6、7、10、11、 12}ですが、それらのIDは2つの異なるサブツリーの一部です。 ( node.children.Descendants:

は、 "X" を取得し、そのすべての子...

where Path = "1" || Path.StartsWith("1,") 

だけのxの子を取得するには...

where Path.StartsWith("1,") 
+0

素敵な解決策、someones - 私は - "シンプル"が最高だと思う! –

0
/// <summary> 
    /// Allows to recursively select descendants as plain collection 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    /// <param name="source"></param> 
    /// <param name="DescendBy"></param> 
    /// <returns></returns> 

    public static IEnumerable<T> Descendants<T>(
     this IEnumerable<T> source, Func<T, IEnumerable<T>> DescendBy) 
    { 
     foreach (T value in source) 
     { 
      yield return value; 

      foreach (var child in DescendBy(value).Descendants(DescendBy)) 
      { 
       yield return child; 
      } 
     } 
    } 

の使用するにはnode => node.children);

0

あなたは次のようにインナーテーブル自体でのLINQで結合を実行する必要があります。

from root in TableName 
join subnodes in TableName on root.Id equals subnodes.ParentId 
select new { Name } 

これは、親IDがサブノード

おかげと改名同じテーブルでIDで一致したすべてのそれらのレコードを取得します

関連する問題