Tuesday 15 May 2018

Linq CopyToDataTable extension for anonymous type IEnumerable

Casting Enumerable into List, Array is to common but sometime we also need to projection in to DataTable. Though there is one inbuilt CopyToDataTable<DataRow>() to get DataTable, but it only works with IEnumerable<DataRow>. Where as sometime we also required casting with anonymous type which we are getting through join or group by Linq query. Here I am providing both predefined and Custom Extension method which will solve our problem.

Predefined Snippet:


var allSubscriptions = from license in licensesDataTable.AsEnumerable()
                                          where license.Field<bool>("IsExpired") == true
                                          select license;
            DataTable expiredSubscriptions = allSubscriptions.CopyToDataTable<DataRow>();



Custom Extension Method:

public static class EnumerableExtensions
    {
        public static DataTable CopyToDataTable(this IEnumerable<object> data)
        {
            var parseDT = new DataTable();
            data.Select((r, i) => new { Key = i, Value = r }).ToList().ForEach(r =>
            {
                if (r.Key == 0)
                {
                    r.Value.GetType().GetProperties().ToList().ForEach(p =>
                    {
                        parseDT.Columns.Add(p.Name, p.PropertyType);
                    });
                }
                var row = parseDT.NewRow();
                r.Value.GetType().GetProperties().ToList().ForEach(p =>
                {
                    row[p.Name] = p.GetValue(r.Value, null);
                });
                parseDT.Rows.Add(row);
 
            });
            return parseDT;
        }
    }

Small Example:


using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace LinqGroupByIntoDataTable
{
 
    public static class EnumerableExtensions
    {
        public static DataTable CopyToDataTable(this IEnumerable<object> data)
        {
            var parseDT = new DataTable();
            data.Select((r, i) => new { Key = i, Value = r }).ToList().ForEach(r =>
            {
                if (r.Key == 0)
                {
                    r.Value.GetType().GetProperties().ToList().ForEach(p =>
                    {
                        parseDT.Columns.Add(p.Name, p.PropertyType);
                    });
                }
                var row = parseDT.NewRow();
                r.Value.GetType().GetProperties().ToList().ForEach(p =>
                {
                    row[p.Name] = p.GetValue(r.Value, null);
                });
                parseDT.Rows.Add(row);
 
            });
            return parseDT;
        }
    }
    class Program
    {
 
        static void Main(string[] args)
        {
            var dt = GetTable();
            var grp = from row in dt.AsEnumerable()
                      group row by row.Field<string>("City"into rowGroup
                      select new
                      {
                          City = rowGroup.Key,
                          Name = rowGroup.Min(r => r.Field<string>("Name")),
                          ID = rowGroup.Min(r => r.Field<int>("ID"))
                      };
 
 
            foreach (var key in grp)
 
            {
                Console.Write(key.City + " " + key.Name);
                Console.WriteLine();
            }
 
 
            var dtNew = grp.CopyToDataTable();
 
 
            Console.ReadKey();
        }
 
        static DataTable GetTable()
        {
            DataTable table = new DataTable();
            table.Columns.Add("ID"typeof(int));
            table.Columns.Add("City"typeof(string));
            table.Columns.Add("Name"typeof(string));
            table.Columns.Add("Date"typeof(DateTime));
 
            table.Rows.Add(25, "Delhi""Raj"DateTime.Now);
            table.Rows.Add(26, "Delhi""Suman"DateTime.Now);
            table.Rows.Add(10, "Pune""Ankur"DateTime.Now);
            table.Rows.Add(21, "Patna""Abhi"DateTime.Now);
            return table;
        }
 
 
    }
 
}

Output: