1

Id、parentId、descriptionを含むデータテーブルを取得しました。リレーショナルテーブル構造です。

ツリービューでアイテムの現在選択されているIDである関数にパラメーターを渡せるようにしたい。関連するすべての子行を含むデータテーブルを返したいのですが、関係の先頭はparentIdがnullです...など

このLINQを実行したい

どんな助けでも歓迎します。

enter code here var kids = ( from p in dt.AsEnumerable()
                     where p.Field<Int32?>( "ParentId" ) == parentId
                     select new
                     {
                         parent = p,
                         child = from c in dt.AsEnumerable()
                                 where c.Field<Int32?>( "ParentId" ) == p.Field<Int32>( "Id" )
                                 select new
                                 {
                                     child = c
                                 }
                     } ).ToList();

以下は私が使用しているデータであり、期待どおりに機能させることができません。たぶん、私たちは同じ最終結果について話しているのではないか、私は何かひどいものを見逃しています。

これが私が持っているコードであり、parentIdに57の値を渡すと、子に2行戻ります。

QuotationItemId=58および71

QuotationItemId 59、60、55、56、61も取得することを期待します

        var lookup = dt.AsEnumerable().ToLookup( p => p.Field<int?>( "ParentId" ) );
        var children = lookup[parentId].ToList();

データダンプ

4

2 に答える 2

5

これがあなたにできることです:

var lookup =
    dt
        .AsEnumerable()
        .ToLookup(p => p.Field<int?>("ParentId"));

ルート要素が必要な場合は、次のようにします。

var roots = lookup[null];

そして、あなたが子供を欲しければ、与えられてparentId、あなたはこれをします:

var children = lookup[parentId];

簡単ですね


これがあなたの編集に基づくいくつかのコードです。

匿名タイプを使用してアイテムのリストを定義しました。

var items = new []
{
    new { QuotationItemId = 54, ParentId = (int?)null, Description = "0000", },
    new { QuotationItemId = 55, ParentId = (int?)60, Description = "Product 55", },
    new { QuotationItemId = 56, ParentId = (int?)60, Description = "Product 56", },
    new { QuotationItemId = 57, ParentId = (int?)54, Description = "Category 57", },
    new { QuotationItemId = 58, ParentId = (int?)57, Description = "Sub Category 58", },
    new { QuotationItemId = 59, ParentId = (int?)58, Description = "Product 59", },
    new { QuotationItemId = 60, ParentId = (int?)58, Description = "Standard Ratel", },
    new { QuotationItemId = 61, ParentId = (int?)60, Description = "Product 61", },
    new { QuotationItemId = 62, ParentId = (int?)null, Description = "Stage 62", },
    new { QuotationItemId = 63, ParentId = (int?)62, Description = "Product 63", },
    new { QuotationItemId = 64, ParentId = (int?)62, Description = "Product 64", },
    new { QuotationItemId = 65, ParentId = (int?)62, Description = "Category 65", },
    new { QuotationItemId = 66, ParentId = (int?)65, Description = "Sub Category66", },
    new { QuotationItemId = 67, ParentId = (int?)66, Description = "Product 67", },
    new { QuotationItemId = 68, ParentId = (int?)66, Description = "Standard Rate 2", },
    new { QuotationItemId = 69, ParentId = (int?)68, Description = "Product 69", },
    new { QuotationItemId = 71, ParentId = (int?)57, Description = "Sub Category 71", },
    new { QuotationItemId = 72, ParentId = (int?)54, Description = "Category 72", },
    new { QuotationItemId = 73, ParentId = (int?)72, Description = "Sub Category73", },
    new { QuotationItemId = 74, ParentId = (int?)73, Description = "Product 74", },
    new { QuotationItemId = 75, ParentId = (int?)73, Description = "Product 75", },
    new { QuotationItemId = 77, ParentId = (int?)null, Description = "qqqqqqqqqq", },
    new { QuotationItemId = 78, ParentId = (int?)null, Description = "zzzzzz", },
    new { QuotationItemId = 79, ParentId = (int?)null, Description = "Test 12345", },
    new { QuotationItemId = 80, ParentId = (int?)null, Description = "456", },
    new { QuotationItemId = 81, ParentId = (int?)null, Description = "tttt", },
    new { QuotationItemId = 82, ParentId = (int?)null, Description = "reddddy777", },
    new { QuotationItemId = 83, ParentId = (int?)null, Description = "bbbbbbbbbbbb", },
    new { QuotationItemId = 84, ParentId = (int?)null, Description = "nnnnnnnnnnnnn", },
};

また、LINQPadを使用すると、ルックアップは次のように機能します。

var lookup = items.ToLookup(x => x.ParentId);

lookup[58].Dump();
lookup[60].Dump();

LINQPadからのスクリーンダンプ

完全に再帰するわけではないことに注意してください。

ずっと再帰したい場合は、再帰関数を定義する必要があります。これを試して:

Func<IEnumerable<Quotation>, IEnumerable<Quotation>> recurse = null;
recurse = qs =>
{
    return
        qs
            .Concat(
                from q in qs
                from q2 in recurse(lookup[q.QuotationItemId])
                select q2);
};

recurse(lookup[57]).Dump();

そしてそれはあなたに与えます:

LINQPadイメージダンプ

それはあなたが期待していることだと思います。

于 2012-06-24T11:53:14.797 に答える
-1

次のコマンドで簡単に選択できます。

var kids = from p in db.Items
           where p.parentId == parentId
           select p

次にkids.Items、リストとして:があります。foreachしたがって、次のような単純なループで子を取得できます。

foreach(Item item in kids.Items)

それが役に立てば幸い。

于 2012-06-24T11:43:58.223 に答える