将数据表转换为树状类结构

时间:2016-07-30 12:06:45

标签: c# datatable

我有这个数据表

Name    Amount  Category
sample  100.00  1
sample  100.00  1
aasdas  11.00   1
asd     1.00    2
sadjas  1.00    2
sadjas  1.00    2
asdasd  1.00    3
asdasd  1.00    3
test    10.00   3

我有这个班级

public class ProductListModel
{
    public string CategoryName { get; set; }
    public List<ProductModel> prodList { get; set; }
}

此类的每个实例都包含具有此定义的产品模型列表

public class ProductModel
{
    public string Name{ get; set; }
    public double Amount { get; set; }
}

如何将此数据表转换为适合ProductListModel类的定义?

因此输出将采用这种形式(仅用于可视化):

// Group by category 1
-- ProductListModel
     --CategoryName = 1
     -- ProdList 
        -- Name = sample, amount = 100.00       
        -- Name = sample, amount = 100.00       
        -- Name = aasdas, amount = 11.00   

// Group by category 2
-- ProductListModel
     --CategoryName = 2
     -- ProdList 
        -- Name = asd, amount = 1.00       
        -- Name = sadjas, amount = 1.00       
        -- Name = sadjas, amount = 1.00      

// Group by category 3      
-- ProductListModel
     --CategoryName = 3
     -- ProdList 
        -- Name = asdasd, amount = 1.00       
        -- Name = asdasd, amount = 1.00      

我试过但是我被卡住了:P

3 个答案:

答案 0 :(得分:1)

这可能吗?这会将类别放在列表中,并将相应的产品放在类别中。 (虽然这是未经测试的)

List<ProductListModel> productCategories = new List<ProductListModel>();

foreach (DataRow row in dataTable.Rows) // Go through all data rows
{
    if (!productCategories.Any(pc => pc.CategoryName == (string)row[2])) // if the product's category is not registered
        productCategories.Add(new ProductListModel() { CategoryName = (string)row[2] } ); // Then add the category to the category list

    // Add the current product (row) to the first registered category that matches the product's own
    productCategories.First(pc => pc.CategoryName == (string)row[2]).prodList.Add(new ProductModel() 
    { 
        Name = (string)row[0], 
        Amount = double.Parse((string)row[1]) 
    }); 
}

我希望这会有所帮助。

修改

我稍微更改了代码,以便重复产品可以堆叠它们(如果有意义的话):

List<ProductListModel> productCategories = new List<ProductListModel>();

foreach (DataRow row in dataTable.Rows)
{
    if (!productCategories.Any(pc => pc.CategoryName == (string)row[2]))
        productCategories.Add(new ProductListModel() { CategoryName = (string)row[2] });

    ProductListModel currentCategory = productCategories.First(pc => pc.CategoryName == (string)row[2]);

    if (currentCategory.prodList.Any(pr => pr.Name == (string)row[0]))
        currentCategory.prodList.First(pr => pr.Name == (string)row[0]).Amount += double.Parse((string)row[1]);
    else
        currentCategory.prodList.Add(new ProductModel() { Name = (string)row[0], Amount = double.Parse((string)row[1]) });
}

答案 1 :(得分:1)

你可以像这样“简化”它

var productList = datatable.Rows.Cast<DataRow>()
    .GroupBy(r => r["Category"] + "").Select(g => new ProductListModel {
        CategoryName = g.Key,
        prodList = g.Select(r => new ProductModel {
            Name = r["Name"] + "",
            Amount = (double)r["Amount"]
        }).ToList()
    }).ToList();

答案 2 :(得分:0)

我解决了这个问题

List<ProductListModel> productList = new List<ProductListModel>();

foreach (var row in datatable.AsEnumerable())
{
    var categoryId = row.Field<string>("Category");
    var product = new ProductModel
    {
        Name = row.Field<string>("Name"),
        Amount = row.Field<double>("Amount")
    };

    // Build each category
    if (!productList.Any(x => x.CategoryName == categoryId))
    {
        var itemList = new List<ProductModel>();

        itemList.Add(product);
        productList.Add(new ProductListModel { CategoryName = categoryId, prodList = itemList });
    }
    else
    {
        var existingprodList = productList.Where(x => x.CategoryName == categoryId).FirstOrDefault();
        existingprodList.prodList.Add(product);
    }
}