C# Convert List<T>, DataTable and Anonymous Object Row to Column

Convert columns to rows using LINQ

 In this article we will do the same thing, but using C#’s arrays and datatables, using the power of LINQ or Lambda expressions

C# array collection or List<T> rows to columns to DataTable

Here is the C# object

var data = new[] {

              new { Product = "Product 1", Year = 2009, Sales = 1212 },

              new { Product = "Product 2", Year = 2009, Sales = 522 },

              new { Product = "Product 1", Year = 2010, Sales = 1337 },

              new { Product = "Product 2", Year = 2011, Sales = 711 },

              new { Product = "Product 2", Year = 2012, Sales = 2245 },

              new { Product = "Product 3", Year = 2012, Sales = 1000 }

          };

var pivotTable1 = data.ToPivotTable(item => item.Year, item => item.Product, items => items.Any() ? items.Sum(x => x.Sales) : 0);

jsonStr = JsonConvert.SerializeObject(pivotTable);


//Row to column

Below is the extension method we defined

public static DataTable ToPivotTable<T, TColumn, TRow, TData>(

    this IEnumerable<T> source,

    Func<T, TColumn> columnSelector,

    Expression<Func<T, TRow>> rowSelector,

    Func<IEnumerable<T>, TData> dataSelector)

        {

            DataTable table = new DataTable();

            var rowName = ((MemberExpression)rowSelector.Body).Member.Name;

            table.Columns.Add(new DataColumn(rowName));

            var columns = source.Select(columnSelector).Distinct();

  

            foreach (var column in columns)

                table.Columns.Add(new DataColumn(column.ToString()));

  

            var rows = source.GroupBy(rowSelector.Compile())

                             .Select(rowGroup => new

                             {

                                 Key = rowGroup.Key,

                                 Values = columns.GroupJoin(

                                     rowGroup,

                                     c => c,

                                     r => columnSelector(r),

                                     (c, columnGroup) => dataSelector(columnGroup))

                             });

  

            foreach (var row in rows)

            {

                var dataRow = table.NewRow();

                var items = row.Values.Cast<object>().ToList();

                items.Insert(0, row.Key);

                dataRow.ItemArray = items.ToArray();

                table.Rows.Add(dataRow);

            }

  

            return table;

        }

You can create a static class for the extension method and put it there.
To convert year values ​​into columns and get a pivot table:

C# Convert List<T> collection rows to anonymous object collection

 After converting the columns to rows, you may want to get a List<dynamic> or dynamic[] instead of getting a DataTable. It's very convenient in ASP. NET Web API returns a JSON response.
To do this, I updated the extension method to get the dynamic object. Use the following extension method:
?

public static List<dynamic>  ToPivotArray<T, TColumn, TRow, TData>(

this IEnumerable<T> source,

Func<T, TColumn> columnSelector,

Expression<Func<T, TRow>> rowSelector,

Func<IEnumerable<T>, TData> dataSelector)

       {

  

           var arr = new List<object>();

           var cols = new List<string>();

           String rowName = ((MemberExpression)rowSelector.Body).Member.Name;

           var columns = source.Select(columnSelector).Distinct();      

  

           cols =(new []{ rowName}).Concat(columns.Select(x=>x.ToString())).ToList();

   

           var rows = source.GroupBy(rowSelector.Compile())

                            .Select(rowGroup => new

                            {

                                Key = rowGroup.Key,

                                Values = columns.GroupJoin(

                                    rowGroup,

                                    c => c,

                                    r => columnSelector(r),

                                    (c, columnGroup) => dataSelector(columnGroup))

                            }).ToArray();

   

           foreach (var row in rows)

           {

               var items = row.Values.Cast<object>().ToList();

               items.Insert(0, row.Key);

               var obj = GetAnonymousObject(cols, items);

               arr.Add(obj);              

           }

           return arr.List();

       }

 private static dynamic GetAnonymousObject(IEnumerable<string> columns, IEnumerable<object> values)

       {

           IDictionary<string, object> eo = new ExpandoObject() as IDictionary<string, object>;

           int i;

           for (i = 0; i < columns.Count(); i++)

           {

               eo.Add(columns.ElementAt<string>(i), values.ElementAt<object>(i));

           }

           return to him;

       }

ExpandoObject is used to create dynamic objects

Now, to convert rows to columns and get dynamic array

C# Convert Datatable rows to Datatable

Let's have a data table with the same data

DataTable myDataTable = new DataTable();

myDataTable.Columns.AddRange(new DataColumn[3] { new DataColumn("Product"), 

new DataColumn("Year", typeof(int)), new DataColumn("Sales", typeof(int)) });

myDataTable.Rows.Add("Product 1", 2009, 1212);

myDataTable.Rows.Add("Product 2", 2009, 522);

myDataTable.Rows.Add("Product 1", 2010, 1337);

myDataTable.Rows.Add("Product 2", 2011, 711);

myDataTable.Rows.Add("Product 2", 2012, 2245);

myDataTable.Rows.Add("Product 3", 2012, 1000);

You can use the same extension method to get a row-to-column DataTable as shown below.

DataTable to List<dynamic>:

If you need to convert a DataTable to a List of dynamic objects, then use the following extension method:

public static List<dynamic> ToDynamicList(this DataTable dt)

{

           var list = new List<dynamic>();

           foreach (DataRow row in dt.Rows)

           {

               dynamic dyn = new ExpandoObject();

               list.Add(dyn);

               foreach (DataColumn column in dt.Columns)

               {

                   var dic = (IDictionary<string, object>)dyn;

                   dic[column.ColumnName] = row[column];

               }

           }

           return list;

}

Guess you like

Origin blog.csdn.net/qq_26695613/article/details/132558327