How to Convert IEnumerable to DataTable\DataView

IEnumerable doesn't have have out-of-box support for some features (like Sorting,Grouping)...that drag you in some cases...
Ok...then, how we use those features?

The other way around is to convert the IEnumerable to DataTable\DataView and use desired the features.

Namespace:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Diagnostics;
using System.Windows.Data;
using System.ComponentModel;
using System.Reflection;

Usage:
public DataView Get_Process()
{
var query = Process.GetProcesses()
.OrderBy(proc => proc.ProcessName)
.Select(proc => new
{
Id = proc.Id,
Name = proc.ProcessName,
Memory = proc.WorkingSet64,
MainWindowTitle = proc.MainWindowTitle,
Priority = proc.BasePriority
});

return (query.CopyToDataTable()).DefaultView;
}

Library:

public static class CustomLINQtoDataSetMethods
{
public static DataTable CopyToDataTable(this IEnumerable source)
{
return new ObjectShredder().Shred(source, null, null);
}

public static DataTable CopyToDataTable(this IEnumerable source,
DataTable table, LoadOption? options)
{
return new ObjectShredder().Shred(source, table, options);
}

}
public class ObjectShredder
{
private System.Reflection.FieldInfo[] _fi;
private System.Reflection.PropertyInfo[] _pi;
private System.Collections.Generic.Dictionary _ordinalMap;
private System.Type _type;

// ObjectShredder constructor.
public ObjectShredder()
{
_type = typeof(T);
_fi = _type.GetFields();
_pi = _type.GetProperties();
_ordinalMap = new Dictionary();
}

///
/// Loads a DataTable from a sequence of objects.
///

/// The sequence of objects to load into the DataTable.
/// The input table. The schema of the table must match that
/// the type T. If the table is null, a new table is created with a schema
/// created from the public properties and fields of the type T.
/// Specifies how values from the source sequence will be applied to
/// existing rows in the table.
/// A DataTable created from the source sequence.
public DataTable Shred(IEnumerable source, DataTable table, LoadOption? options)
{
// Load the table from the scalar sequence if T is a primitive type.
if (typeof(T).IsPrimitive)
{
return ShredPrimitive(source, table, options);
}

// Create a new table if the input table is null.
if (table == null)
{
table = new DataTable(typeof(T).Name);
}

// Initialize the ordinal map and extend the table schema based on type T.
table = ExtendTable(table, typeof(T));

// Enumerate the source sequence and load the object values into rows.
table.BeginLoadData();
using (IEnumerator e = source.GetEnumerator())
{
while (e.MoveNext())
{
if (options != null)
{
table.LoadDataRow(ShredObject(table, e.Current), (LoadOption)options);
}
else
{
table.LoadDataRow(ShredObject(table, e.Current), true);
}
}
}
table.EndLoadData();

// Return the table.
return table;
}

public DataTable ShredPrimitive(IEnumerable source, DataTable table, LoadOption? options)
{
// Create a new table if the input table is null.
if (table == null)
{
table = new DataTable(typeof(T).Name);
}

if (!table.Columns.Contains("Value"))
{
table.Columns.Add("Value", typeof(T));
}

// Enumerate the source sequence and load the scalar values into rows.
table.BeginLoadData();
using (IEnumerator e = source.GetEnumerator())
{
Object[] values = new object[table.Columns.Count];
while (e.MoveNext())
{
values[table.Columns["Value"].Ordinal] = e.Current;

if (options != null)
{
table.LoadDataRow(values, (LoadOption)options);
}
else
{
table.LoadDataRow(values, true);
}
}
}
table.EndLoadData();

// Return the table.
return table;
}

public object[] ShredObject(DataTable table, T instance)
{

FieldInfo[] fi = _fi;
PropertyInfo[] pi = _pi;

if (instance.GetType() != typeof(T))
{
// If the instance is derived from T, extend the table schema
// and get the properties and fields.
ExtendTable(table, instance.GetType());
fi = instance.GetType().GetFields();
pi = instance.GetType().GetProperties();
}

// Add the property and field values of the instance to an array.
Object[] values = new object[table.Columns.Count];
foreach (FieldInfo f in fi)
{
values[_ordinalMap[f.Name]] = f.GetValue(instance);
}

foreach (PropertyInfo p in pi)
{
values[_ordinalMap[p.Name]] = p.GetValue(instance, null);
}

// Return the property and field values of the instance.
return values;
}

public DataTable ExtendTable(DataTable table, Type type)
{
// Extend the table schema if the input table was null or if the value
// in the sequence is derived from type T.
foreach (FieldInfo f in type.GetFields())
{
if (!_ordinalMap.ContainsKey(f.Name))
{
// Add the field as a column in the table if it doesn't exist
// already.
DataColumn dc = table.Columns.Contains(f.Name) ? table.Columns[f.Name]
: table.Columns.Add(f.Name, f.FieldType);

// Add the field to the ordinal map.
_ordinalMap.Add(f.Name, dc.Ordinal);
}
}
foreach (PropertyInfo p in type.GetProperties())
{
if (!_ordinalMap.ContainsKey(p.Name))
{
// Add the property as a column in the table if it doesn't exist
// already.
DataColumn dc = table.Columns.Contains(p.Name) ? table.Columns[p.Name]
: table.Columns.Add(p.Name, p.PropertyType);

// Add the property to the ordinal map.
_ordinalMap.Add(p.Name, dc.Ordinal);
}
}

// Return the table.
return table;
}
}


Reference : MSDN

Comments

Popular posts from this blog

What is the difference "Source vs. RelativeSource vs. ElementName"