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,因此它不像 ParentID,因为这些 ID 可能具有相同的种子值)。这是可行的吗?

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 回答