How to create new columns from List<t> values?

时间:2018-12-19 11:24:02

标签: c# list linq datatable

I've a list like this:

internal class Order
{
    public Order()
    {
    }

    public string ProductID { get; set; }
    public int Amount { get; set; }
    public string Date { get; set; }
}

List<Order> orderList = new List<Order>() 
{
    new Order(){ ProductID="12345", Amount=300, Date = "2018-12-19"},
    new Order(){ ProductID="12345", Amount=0, Date = "2018-12-20"},
    new Order(){ ProductID="12345", Amount=200, Date = "2018-12-21"},
    new Order(){ ProductID="12345", Amount=250, Date = "2018-12-22"},
    new Order(){ ProductID="12345", Amount=30, Date = "2018-12-23"},
    new Order(){ ProductID="67898", Amount=20, Date = "2018-12-20"},
    new Order(){ ProductID="67898", Amount=30, Date = "2018-12-21"},
    new Order(){ ProductID="67898", Amount=40, Date = "2018-12-22"},
    new Order(){ ProductID="67898", Amount=50, Date = "2018-12-23"},
    new Order(){ ProductID="67898", Amount=130, Date = "2018-12-24"}
};

In this situation, when I convert the list to DataTable and export it to excel, I get this:

Current table

I want to create new columns from Date values and list them by ProductID. How can I convert this List to DataTable to see like this:

enter image description here

2 个答案:

答案 0 :(得分:1)

您可以使用GroupByExpandoObject来实现:

var result = new List<ExpandoObject>();
foreach (var orders in orderList.GroupBy(obj => obj.ProductID))
{
    var record = new ExpandoObject();
    foreach (var order in orders.AsEnumerable())
    {
        ((IDictionary<string, object>)record).Add(order.Date, order.Amount);
    }
    result.Add(record);
}

答案 1 :(得分:0)

您想要一个像excel中一样的数据透视表。下面的代码创建两个数据表。您列出的第一个基数。然后使用第一个表并创建第二个数据透视表

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication93
{
    class Program
    {
        static void Main(string[] args)
        {
            Order order = new Order();
            DataTable dt = order.MakeTable();

            //now create piviot table
            string[] dates = dt.AsEnumerable().Select(x => x.Field<string>("Date")).Distinct().ToArray();

            DataTable pivot = new DataTable();
            pivot.Columns.Add("ProductID", typeof(string));
            foreach (string date in dates)
            {
                pivot.Columns.Add(date, typeof(int));
            }

            var groups = dt.AsEnumerable().GroupBy(x => x.Field<string>("ProductID")).ToList();

            foreach(var group in groups)
            {
                DataRow newRow = pivot.Rows.Add();
                newRow["ProductID"] = group.Key;
                foreach (var col in group)
                {
                    newRow[col.Field<string>("Date")] = col.Field<int>("Amount");
                }

            }

        }
    }
    internal class Order
    {
        public Order()
        {
        }

        public string ProductID { get; set; }
        public int Amount { get; set; }
        public string Date { get; set; }

        public DataTable MakeTable()
        {
            DataTable dt = new DataTable();

            List<Order> orderList = new List<Order>() {
                new Order(){ ProductID="12345", Amount=300, Date = "2018-12-19"},
                new Order(){ ProductID="12345", Amount=0, Date = "2018-12-20"},
                new Order(){ ProductID="12345", Amount=200, Date = "2018-12-21"},
                new Order(){ ProductID="12345", Amount=250, Date = "2018-12-22"},
                new Order(){ ProductID="12345", Amount=30, Date = "2018-12-23"},
                new Order(){ ProductID="67898", Amount=20, Date = "2018-12-20"},
                new Order(){ ProductID="67898", Amount=30, Date = "2018-12-21"},
                new Order(){ ProductID="67898", Amount=40, Date = "2018-12-22"},
                new Order(){ ProductID="67898", Amount=50, Date = "2018-12-23"},
                new Order(){ ProductID="67898", Amount=130, Date = "2018-12-24"}
            };

            foreach (var prop in this.GetType().GetProperties())
            {
                string typeName = prop.PropertyType.FullName;
                Type systemType = System.Type.GetType(typeName);
                dt.Columns.Add(prop.Name, systemType);
            }
            foreach (Order row in orderList)
            {
                object[] data = row.GetType().GetProperties().Select(x => x.GetValue(row, null)).ToArray();
                dt.Rows.Add(data);
            }

            return dt;
        }
    }
}