namespace ConsoleApplication { using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Xml.Serialization; using Microshaoft; public class Class1 { //[STAThread] [Serializable] public class Entry { [XmlElement("F1")] public string F1 { get; set; } [XmlElement("F2")] public int F2 { get; set; } [XmlAttribute("F3")] public DateTime F3 { get; set; } public DateTime? FF3 { get; set; } [XmlArrayItem("Entry2", typeof(Entry2))] [XmlArray("Entry2S")] public Entry2[] Entry2S { get; set; } }; public class Entry2 { [XmlElement("F1")] public string F1 { get; set; } [XmlElement("F2")] public int F2 { get; set; } [XmlAttribute("F3")] public DateTime F3 { get; set; } public DateTime? FF3 { get; set; } }; static void Main(string[] args) { var list = new List<Entry>() { new Entry() { F1 = "a" , F2= 1 , F3 = DateTime.Now , FF3 = null , Entry2S = new [] { new Entry2 () { F1 = "sadasd" , F2 = 10 , F3 = DateTime.Now } , new Entry2 () { F1 = "sadasd" , F2 = 10 , F3 = DateTime.Now } , new Entry2 () { F1 = "sadasd" , F2 = 10 , F3 = DateTime.Now } } } ,new Entry() { F1= "b" , F2= 2 , F3 = DateTime.Now , FF3 = null , Entry2S = new [] { new Entry2 () { F1 = "sadasd" , F2 = 10 , F3 = DateTime.Now } , new Entry2 () { F1 = "sadasd" , F2 = 10 , F3 = DateTime.Now } , new Entry2 () { F1 = "sadasd" , F2 = 10 , F3 = DateTime.Now } } } ,new Entry() { F1= "c" , F2= 3 , F3 = DateTime.Now , FF3 = null , Entry2S = new [] { new Entry2 () { F1 = "sadasd" , F2 = 10 , F3 = DateTime.Now } , new Entry2 () { F1 = "sadasd" , F2 = 10 , F3 = DateTime.Now } , new Entry2 () { F1 = "sadasd" , F2 = 10 , F3 = DateTime.Now } } } }; var dataTable = list.ToDataTable<Entry>(); DataTableHelper.DataTableRowsForEach ( dataTable , (x, y) => { Console.WriteLine("{1}{0}{2}", " : ", y, x.ColumnName); return false; } , (x) => { Console.WriteLine("{1}", " : ", x.Count); return false; } , (x, y, z, w) => { Console.WriteLine("{1}{0}{2}{0}{3}{0}{4}", " : ", x.ColumnName, y, z, w); return false; } , (x, y, z) => { Console.WriteLine("{1}{0}{2}", " : ", x.Count, z); return false; } ); dataTable = DataTableHelper.GenerateEmptyDataTable<Entry>(); Console.ReadLine(); } } } namespace Microshaoft { using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; public static class DataTableHelper { private static List<Type> _typesWhiteList = new List<Type>() { typeof(int) //, typeof(int?) , typeof(long) //, typeof(long?) , typeof(string) , typeof(DateTime) //, typeof(DateTime?) }; public static DataTable GenerateEmptyDataTable<T>() { var type = typeof(T); return GenerateEmptyDataTable(type); } public static DataTable GenerateEmptyDataTable(Type type) { var properties = type.GetProperties().Where ( (x) => { return _typesWhiteList.Any ( (xx) => { return x.PropertyType == xx; } ); } ) .ToList(); DataTable dataTable = null; DataColumnCollection dataColumnsCollection = null; properties.ForEach ( (x) => { if (dataTable == null) { dataTable = new DataTable(); } if (dataColumnsCollection == null) { dataColumnsCollection = dataTable.Columns; } dataColumnsCollection.Add ( x.Name , x.PropertyType ); } ); return dataTable; } public static void DataTableRowsForEach ( DataTable dataTable , Func<DataColumn,int, bool> processHeaderDataColumnFunc = null , Func<DataColumnCollection, bool> processHeaderDataColumnsFunc = null , Func<DataColumn, int, object, int, bool> processRowDataColumnFunc = null , Func<DataColumnCollection, DataRow, int, bool> processRowFunc = null ) { DataColumnCollection dataColumnCollection = null; int i = 0; bool r = false; if (processHeaderDataColumnFunc != null) { dataColumnCollection = dataTable.Columns; foreach (DataColumn dc in dataColumnCollection) { i ++; r = processHeaderDataColumnFunc(dc, i); if (r) { break; } } } if (processHeaderDataColumnsFunc != null) { if (dataColumnCollection == null) { dataColumnCollection = dataTable.Columns; } r = processHeaderDataColumnsFunc(dataColumnCollection); if (r) { return; } } DataRowCollection drc = null; if ( processRowDataColumnFunc != null || processRowFunc != null ) { drc = dataTable.Rows; if ( ( processRowDataColumnFunc != null || processRowFunc != null ) && dataColumnCollection == null ) { dataColumnCollection = dataTable.Columns; } i = 0; var j = 0; foreach (DataRow dataRow in drc) { i ++; foreach (DataColumn dc in dataColumnCollection) { if (processRowDataColumnFunc != null) { j ++; r = processRowDataColumnFunc ( dc , j , dataRow[dc] , i ); if (r) { j = 0; break; } } } if (processRowFunc != null) { processRowFunc(dataColumnCollection, dataRow, i); } } } } } } namespace Microshaoft { using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Reflection; public static class ExtensionMethodsManager { private static List<Type> _typesWhiteList = new List<Type>() { typeof(int) //, typeof(int?) , typeof(long) //, typeof(long?) , typeof(string) , typeof(DateTime) //, typeof(DateTime?) }; private class PropertyAccessor { public Func<object, object> Getter; public Action<object, object> Setter; public PropertyInfo Property; } private static Dictionary < Type , Dictionary < string , PropertyAccessor > > _typesPropertiesAccessors = new Dictionary<Type, Dictionary<string, PropertyAccessor>>(); private static Dictionary<string, PropertyAccessor> GetTypePropertiesAccessors(Type type) { var properties = type.GetProperties(); Dictionary<string, PropertyAccessor> dictionary = null; Array.ForEach ( properties , (x) => { if ( _typesWhiteList.Any ( (xx) => { return xx == x.PropertyType; } ) ) { var accessor = new PropertyAccessor() { Getter = DynamicPropertyAccessor.CreateGetPropertyValueFunc(type, x.Name) , Setter = DynamicPropertyAccessor.CreateSetPropertyValueAction(type, x.Name) , Property = x }; if (dictionary == null) { dictionary = new Dictionary<string, PropertyAccessor>(); } dictionary.Add(x.Name, accessor); } } ); return dictionary; } public static DataTable ToDataTable<TEntry>(this IEnumerable<TEntry> ie) { var type = typeof(TEntry); var accessors = GetTypePropertiesAccessors(type); var accessorsList = accessors.ToList(); DataTable dataTable = GenerateEmptyDataTable(accessorsList); DataColumnCollection dcc = dataTable.Columns; if (dataTable != null) { using (IEnumerator<TEntry> enumerator = ie.GetEnumerator()) { while (enumerator.MoveNext()) { var row = dataTable.NewRow(); foreach (DataColumn c in dcc) { PropertyAccessor accessor = null; if (accessors.TryGetValue(c.ColumnName, out accessor)) { row[c] = accessor.Getter(enumerator.Current); } } dataTable.Rows.Add(row); } } } return dataTable; } private static DataTable GenerateEmptyDataTable(List<KeyValuePair<string, PropertyAccessor>> accessorsList) { DataTable dataTable = null; accessorsList .ForEach ( (x) => { if (dataTable == null) { dataTable = new DataTable(); } var propertyType = x.Value.Property.PropertyType; var propertyName = x.Value.Property.Name; var column = new DataColumn ( propertyName , propertyType ); dataTable.Columns.Add(column); } ); return dataTable; } public static DataTable ToDataTable<TEntry>(this List<TEntry> list) // where TEntry : new() { var type = typeof(TEntry); var accessors = GetTypePropertiesAccessors(type); var accessorsList = accessors.ToList(); DataTable dataTable = GenerateEmptyDataTable(accessorsList); DataColumnCollection dcc = dataTable.Columns; if (dataTable != null) { list.ForEach ( (x) => { var row = dataTable.NewRow(); foreach (DataColumn c in dcc) { PropertyAccessor accessor = null; if (accessors.TryGetValue(c.ColumnName, out accessor)) { row[c] = accessor.Getter(x); } } dataTable.Rows.Add(row); } ); } return dataTable; } public static List<TEntry> ToList<TEntry>(this DataTable dataTable) where TEntry : new() { var type = typeof(TEntry); var columns = dataTable.Columns; var actions = new Dictionary<string, Action<object, object>>(); foreach (DataColumn c in columns) { var columnName = c.ColumnName; var action = DynamicPropertyAccessor.CreateSetPropertyValueAction ( typeof(TEntry) , columnName ); actions[columnName] = action; } List<TEntry> list = null; var rows = dataTable.Rows; foreach (DataRow r in rows) { var entry = new TEntry(); if (list == null) { list = new List<TEntry>(); } foreach (DataColumn c in columns) { var columnName = c.ColumnName; var action = actions[columnName]; action(entry, r[columnName]); } list.Add(entry); } return list; } } } namespace Microshaoft { using System; using System.Linq; using System.Linq.Expressions; using System.Reflection; public class DynamicPropertyAccessor { private static Assembly GetAssemblyByTypeName(string typeName) { return AppDomain.CurrentDomain.GetAssemblies().First ( (a) => { return a.GetTypes().Any ( (t) => { return (t.FullName == typeName); } ); } ); } public static Func<object, object> CreateGetPropertyValueFunc(string typeName, string propertyName, bool isTypeFromAssembly = false) { Type type; if (isTypeFromAssembly) { var assembly = GetAssemblyByTypeName(typeName); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateGetPropertyValueFunc(type, propertyName); } public static Func<object, object> CreateGetPropertyValueFunc(Type type, string propertyName) { var target = Expression.Parameter(typeof(object), "p"); var castTarget = Expression.Convert(target, type); var getPropertyValue = Expression.Property(castTarget, propertyName); var castPropertyValue = Expression.Convert(getPropertyValue, typeof(object)); var lambda = Expression.Lambda<Func<object, object>>(castPropertyValue, target); return lambda.Compile(); } public static Func<object, TProperty> CreateGetPropertyValueFunc<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false) { Type type; if (isTypeFromAssembly) { var assembly = GetAssemblyByTypeName(typeName); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateGetPropertyValueFunc<TProperty>(type, propertyName); } public static Func<object, TProperty> CreateGetPropertyValueFunc<TProperty>(Type type, string propertyName) { var target = Expression.Parameter(typeof(object), "p"); var castTarget = Expression.Convert(target, type); var getPropertyValue = Expression.Property(castTarget, propertyName); var lambda = Expression.Lambda<Func<object, TProperty>>(getPropertyValue, target); return lambda.Compile(); } public static Func<TProperty> CreateGetStaticPropertyValueFunc<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false) { Type type; if (isTypeFromAssembly) { var assembly = GetAssemblyByTypeName(typeName); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateGetStaticPropertyValueFunc<TProperty>(type, propertyName); } public static Func<TProperty> CreateGetStaticPropertyValueFunc<TProperty>(Type type, string propertyName) { var property = type.GetProperty(propertyName, typeof(TProperty)); var getPropertyValue = Expression.Property(null, property); var lambda = Expression.Lambda<Func<TProperty>>(getPropertyValue, null); return lambda.Compile(); } public static Func<object> CreateGetStaticPropertyValueFunc(Type type, string propertyName) { var property = type.GetProperty(propertyName); var getPropertyValue = Expression.Property(null, property); var castPropertyValue = Expression.Convert(getPropertyValue, typeof(object)); var lambda = Expression.Lambda<Func<object>>(castPropertyValue, null); return lambda.Compile(); } public static Func<object> CreateGetStaticPropertyValueFunc(string typeName, string propertyName, bool isTypeFromAssembly = false) { Type type; if (isTypeFromAssembly) { var assembly = GetAssemblyByTypeName(typeName); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateGetStaticPropertyValueFunc(type, propertyName); } public static Action<object, object> CreateSetPropertyValueAction(Type type, string propertyName) { var property = type.GetProperty(propertyName); var target = Expression.Parameter(typeof(object), "p"); var propertyValue = Expression.Parameter(typeof(object), "p1"); var castTarget = Expression.Convert(target, type); var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType); var getSetMethod = property.GetSetMethod(); if (getSetMethod == null) { getSetMethod = property.GetSetMethod(true); } var call = Expression.Call(castTarget, getSetMethod, castPropertyValue); var lambda = Expression.Lambda<Action<object, object>>(call, target, propertyValue); return lambda.Compile(); } public static Action<object, object> CreateSetPropertyValueAction(string typeName, string propertyName, bool isTypeFromAssembly = false) { Type type; if (isTypeFromAssembly) { var assembly = GetAssemblyByTypeName(typeName); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateSetPropertyValueAction(type, propertyName); } public static Action<object, TProperty> CreateSetPropertyValueAction<TProperty>(Type type, string propertyName) { var property = type.GetProperty(propertyName); var target = Expression.Parameter(typeof(object), "p"); var propertyValue = Expression.Parameter(typeof(TProperty), "p1"); var castTarget = Expression.Convert(target, type); var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType); var getSetMethod = property.GetSetMethod(); if (getSetMethod == null) { getSetMethod = property.GetSetMethod(true); } var call = Expression.Call(castTarget, getSetMethod, castPropertyValue); var lambda = Expression.Lambda<Action<object, TProperty>>(call, target, propertyValue); return lambda.Compile(); } public static Action<object, TProperty> CreateSetPropertyValueAction<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false) { Type type; if (isTypeFromAssembly) { var assembly = GetAssemblyByTypeName(typeName); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateSetPropertyValueAction<TProperty>(type, propertyName); } public static Action<object> CreateSetStaticPropertyValueAction(Type type, string propertyName) { var property = type.GetProperty(propertyName); var propertyValue = Expression.Parameter(typeof(object), "p"); var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType); var getSetMethod = property.GetSetMethod(); if (getSetMethod == null) { getSetMethod = property.GetSetMethod(true); } var call = Expression.Call(null, getSetMethod, castPropertyValue); var lambda = Expression.Lambda<Action<object>>(call, propertyValue); return lambda.Compile(); } public static Action<object> CreateSetStaticPropertyValueAction(string typeName, string propertyName, bool isTypeFromAssembly = false) { Type type; if (isTypeFromAssembly) { var assembly = GetAssemblyByTypeName(typeName); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateSetStaticPropertyValueAction(type, propertyName); } public static Action<TProperty> CreateSetStaticPropertyValueAction<TProperty>(Type type, string propertyName) { var property = type.GetProperty(propertyName); var propertyValue = Expression.Parameter(typeof(TProperty), "p"); //var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType); var getSetMethod = property.GetSetMethod(); if (getSetMethod == null) { getSetMethod = property.GetSetMethod(true); } var call = Expression.Call(null, getSetMethod, propertyValue); var lambda = Expression.Lambda<Action<TProperty>>(call, propertyValue); return lambda.Compile(); } public static Action<TProperty> CreateSetStaticPropertyValueAction<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false) { Type type; if (isTypeFromAssembly) { var assembly = GetAssemblyByTypeName(typeName); type = assembly.GetType(typeName); } else { type = Type.GetType(typeName); } return CreateSetStaticPropertyValueAction<TProperty>(type, propertyName); } } } |