2

次のようなデータ構造があります。

Category: ID, Name
Manufacturer: ID, Name
Product: ID, CategoryID, ManufacturerID, Name

EF を使用して、次のようなデータを返すストアド プロシージャを呼び出しています。

CategoryID   CategoryName  ManufacturerID  ManufacturerName ProductID ProductName
=================================================================================
1            C1            1               M1               1         P1
1            C1            1               M1               2         P2
1            C1            2               M2               3         P3
2            C2            1               M1               4         P4
2            C2            3               M3               5         P5

EF は、上記のデータをマップするデータ型 (MyFlatDataType) を生成します。

LINQ resursion を使用して、ツリービューに表示できるオブジェクトを構築したいと考えています。

C1
  \_ M1
       \_ P1
       \_ P2
  \_ M2
       \_ P3
C2
  \_ M1
       \_ P4
  \_ M3
       \_ P5

ノードごとに ID (CategoryID、ManufacturerID、または ProductID のいずれかであり、これらの ID は同じシード値を持つ可能性があるため、ParentID のようなものではありません) も保持する必要があることに注意してください。これは実行可能ですか?

4

2 に答える 2

1

これでうまくいくはずです。

//The data rows you're getting from the stored procedure:
IEnumerable<MyFlatDataType> rows = ...;
//The tree structure you requested:
var categories = rows
    .GroupBy(row => new { row.CategoryID, row.CategoryName })
    .Select(categoryGroup => new
    {
        categoryGroup.Key.CategoryID,
        categoryGroup.Key.CategoryName,
        Manufacturers = categoryGroup
            .GroupBy(row => new { row.ManufacturerID, row.ManufacturerName })
            .Select(manufacturerGroup => new
            {
                manufacturerGroup.Key.ManufacturerID,
                manufacturerGroup.Key.ManufacturerName,
                Products = manufacturerGroup
                    .Select(row => new
                    {
                        row.ProductID,
                        row.ProductName
                    })
                    .ToList()
            })
            .ToList()
    })
    .ToList();
于 2012-11-16T07:58:05.643 に答える
0

すべてのコレクションが既にメモリ内にあると仮定すると (orm については何も言わなかった)、結合するだけで済みます。

products
  .Join(cats, x => x.catId, x => x.id, (x, y) => new Projection(){cat = y, p = x})
  .Join(mans, x => x.p.manId, x => x.id, (x, y) => { x.man = y; return x; })
  ;

コードサンプル:

public class Product
{
    public int id;
    public int catId;
    public int manId;
    public string name;
}

public class Man
{
    public int id;
    public string name;
}

public class Cat
{
    public int id;
    public string name;
}

public class Projection
{
    public Cat cat;
    public Man man;
    public Product p;
}


[Fact]
public void Do()
{
    var products = new List<Product>()
       {
           new Product{id=1, catId=1, manId=1, name="1"},
           new Product{id=2, catId=1, manId=1, name="2"},
           new Product{id=3, catId=1, manId=2, name="3"},
           new Product{id=4, catId=2, manId=1, name="4"},
           new Product{id=5, catId=2, manId=3, name="5"},
       };

    var cats = new List<Cat>()
       {
           new Cat() {id = 1, name = "1c"},
           new Cat() {id = 2, name = "2c"}
       };

    var mans = new List<Man>()
       {
           new Man() {id = 1, name = "1m"},
           new Man() {id = 2, name = "2m"},
           new Man() {id = 3, name = "3m"}
       };

    var results = products
        .Join(cats, x => x.catId, x => x.id, (x, y) => new Projection(){cat = y, p = x})
        .Join(mans, x => x.p.manId, x => x.id, (x, y) => { x.man = y; return x; })
        ;

    foreach (var x in results)
    {
        Console.WriteLine("{0} {1} {2} {3} {4} {5}", x.cat.id, x.cat.name, x.man.id, x.man.name, x.p.id, x.p.name);
    }
}
于 2012-11-15T05:15:25.917 に答える