2016-07-30 52 views
0

我有這樣的數據表轉換數據表到樹狀階層結構

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; } 
} 

如何將此數據錶轉換爲適合的定義3210班?

所以輸出會以這種形式(用於可視化只):

// 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

回答

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(); 
+0

這就是我要找的!謝謝 – Sherlock

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]) 
    }); 
} 

我希望這會有所幫助。

編輯

我改變了代碼一點,這樣重複的產品會得到他們的ammouts堆疊(如果是有道理的):

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]) }); 
} 
+0

thansk爲努力,但它不工作,這可以做到沒有循環? – Sherlock

+0

它不起作用?出了什麼問題?結果與你的期望是什麼?循環有什麼問題? – MasterXD

+0

@Sherlock我對代碼做了一些修改。也許你在複製代碼時沒有得到。我也做了另一個版本。 – MasterXD

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); 
    } 
}