IDataReader扩展ToList<T> 改进版
// 最快 和直接循环差不多 public static List < TResult > ToList < TResult > ( this IDataReader dr, bool isClose) where TResult : class , new () { IDataReaderEntityBuilder < TResult > eblist = IDataReaderEntityBuilder < TResult > .CreateBuilder(dr); List < TResult > list = new List < TResult > (); if (dr == null ) return list; while (dr.Read()) list.Add(eblist.Build(dr)); if (isClose) { dr.Close(); dr.Dispose(); dr = null ; } return list; } public static List < TResult > ToList < TResult > ( this IDataReader dr) where TResult : class , new () { return dr.ToList < TResult > ( true ); } // 也慢 public static List < TResult > ToList2 < TResult > ( this IDataReader dr, bool isClose) where TResult : class , new () { List < TResult > oblist = new List < TResult > (); if (dr == null ) return oblist; List < string > drColumns = new List < string > (); int len = dr.FieldCount; for ( int j = 0 ; j < len; j ++ ) drColumns.Add(dr.GetName(j).Trim()); List < PropertyInfo > prlist = new List < PropertyInfo > (); Type t = typeof (TResult); Array.ForEach < PropertyInfo > (t.GetPropertiesCache(), p => { if (drColumns.IndexOf(p.Name) != - 1 ) prlist.Add(p); }); while (dr.Read()) { TResult ob = new TResult(); prlist.ForEach(p => { if (dr[p.Name] != DBNull.Value) p.SetValue(ob, dr[p.Name], null ); }); oblist.Add(ob); } if (isClose) { dr.Close(); dr.Dispose(); dr = null ; } return oblist; } public static List < TResult > ToList2 < TResult > ( this IDataReader dr) where TResult : class , new () { return dr.ToList2 < TResult > ( true ); } // 最慢 public static List < TResult > ToList3 < TResult > ( this IDataReader dr, bool isClose) where TResult : class , new () { List < TResult > list = new List < TResult > (); if (dr == null ) return list; int len = dr.FieldCount; while (dr.Read()) { TResult info = new TResult(); for ( int j = 0 ; j < len; j ++ ) { if (dr[j] == null || string .IsNullOrEmpty(dr[j].ToString())) continue ; info.GetType().GetPropertyCache(dr.GetName(j).Trim()).SetValue(info, dr[j], null ); } list.Add(info); } if (isClose) { dr.Close(); dr.Dispose(); dr = null ; } return list; } public static List < TResult > ToList3 < TResult > ( this IDataReader dr) where TResult : class , new () { return dr.ToList3 < TResult > ( true ); }
谢谢"幸运草"提供更快速的DataReader转实体LIST的代码.我将发在这里:
public class IDataReaderEntityBuilder < Entity > { private static readonly MethodInfo getValueMethod = typeof (IDataRecord).GetMethod( " get_Item " , new Type[] { typeof ( int ) }); private static readonly MethodInfo isDBNullMethod = typeof (IDataRecord).GetMethod( " IsDBNull " , new Type[] { typeof ( int ) }); private delegate Entity Load(IDataRecord dataRecord); private Load handler; private IDataReaderEntityBuilder() { } public Entity Build(IDataRecord dataRecord) { return handler(dataRecord); } public static IDataReaderEntityBuilder < Entity > CreateBuilder(IDataRecord dataRecord) { IDataReaderEntityBuilder < Entity > dynamicBuilder = new IDataReaderEntityBuilder < Entity > (); DynamicMethod method = new DynamicMethod( " DynamicCreateEntity " , typeof (Entity), new Type[] { typeof (IDataRecord) }, typeof (Entity), true ); ILGenerator generator = method.GetILGenerator(); LocalBuilder result = generator.DeclareLocal( typeof (Entity)); generator.Emit(OpCodes.Newobj, typeof (Entity).GetConstructor(Type.EmptyTypes)); generator.Emit(OpCodes.Stloc, result); for ( int i = 0 ; i < dataRecord.FieldCount; i ++ ) { PropertyInfo propertyInfo = typeof (Entity).GetProperty(dataRecord.GetName(i)); Label endIfLabel = generator.DefineLabel(); if (propertyInfo != null && propertyInfo.GetSetMethod() != null ) { generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, i); generator.Emit(OpCodes.Callvirt, isDBNullMethod); generator.Emit(OpCodes.Brtrue, endIfLabel); generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, i); generator.Emit(OpCodes.Callvirt, getValueMethod); generator.Emit(OpCodes.Unbox_Any, dataRecord.GetFieldType(i)); generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod()); generator.MarkLabel(endIfLabel); } } generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ret); dynamicBuilder.handler = (Load)method.CreateDelegate( typeof (Load)); return dynamicBuilder; } }
使用反射的同志们,请放泣使用反射方法转实体类LIST.
DataTable扩展ToList<T> 改进版
// 最快和直接循环差不多 public static List < TResult > ToList < TResult > ( this DataTable dt) where TResult : class , new () { List < TResult > list = new List < TResult > (); if (dt == null ) return list; DataTableEntityBuilder < TResult > eblist = DataTableEntityBuilder < TResult > .CreateBuilder(dt.Rows[ 0 ]); foreach (DataRow info in dt.Rows) list.Add(eblist.Build(info)); dt.Dispose(); dt = null ; return list; } // 也慢 public static List < TResult > ToList2 < TResult > ( this DataTable dt) where TResult : class , new () { List < PropertyInfo > prlist = new List < PropertyInfo > (); Type t = typeof (TResult); Array.ForEach < PropertyInfo > (t.GetPropertiesCache(), p => { if (dt.Columns.IndexOf(p.Name) != - 1 ) prlist.Add(p); }); List < TResult > oblist = new List < TResult > (); foreach (DataRow row in dt.Rows) { TResult ob = new TResult(); prlist.ForEach(p => { if (row[p.Name] != DBNull.Value) p.SetValue(ob, row[p.Name], null ); }); oblist.Add(ob); } return oblist; } // 最慢 public static List < TResult > ToList3 < TResult > ( this DataTable dt) where TResult : class , new () { List < TResult > list = new List < TResult > (); if (dt == null ) return list; int len = dt.Rows.Count; for ( int i = 0 ; i < len; i ++ ) { TResult info = new TResult(); foreach (DataColumn dc in dt.Rows[ 0 ].Table.Columns) { if (dt.Rows[i][dc.ColumnName] == null || string .IsNullOrEmpty(dt.Rows[i][dc.ColumnName].ToString())) continue ; info.GetType().GetPropertyCache(dc.ColumnName).SetValue(info, dt.Rows[i][dc.ColumnName], null ); } list.Add(info); } dt.Dispose(); dt = null ; return list; } public class DataTableEntityBuilder < Entity > { private static readonly MethodInfo getValueMethod = typeof (DataRow).GetMethod( " get_Item " , new Type[] { typeof ( int ) }); private static readonly MethodInfo isDBNullMethod = typeof (DataRow).GetMethod( " IsNull " , new Type[] { typeof ( int ) }); private delegate Entity Load(DataRow dataRecord); private Load handler; private DataTableEntityBuilder() { } public Entity Build(DataRow dataRecord) { return handler(dataRecord); } public static DataTableEntityBuilder < Entity > CreateBuilder(DataRow dataRecord) { DataTableEntityBuilder < Entity > dynamicBuilder = new DataTableEntityBuilder < Entity > (); DynamicMethod method = new DynamicMethod( " DynamicCreateEntity " , typeof (Entity), new Type[] { typeof (DataRow) }, typeof (Entity), true ); ILGenerator generator = method.GetILGenerator(); LocalBuilder result = generator.DeclareLocal( typeof (Entity)); generator.Emit(OpCodes.Newobj, typeof (Entity).GetConstructor(Type.EmptyTypes)); generator.Emit(OpCodes.Stloc, result); for ( int i = 0 ; i < dataRecord.ItemArray.Length; i ++ ) { PropertyInfo propertyInfo = typeof (Entity).GetProperty(dataRecord.Table.Columns[i].ColumnName); Label endIfLabel = generator.DefineLabel(); if (propertyInfo != null && propertyInfo.GetSetMethod() != null ) { generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, i); generator.Emit(OpCodes.Callvirt, isDBNullMethod); generator.Emit(OpCodes.Brtrue, endIfLabel); generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, i); generator.Emit(OpCodes.Callvirt, getValueMethod); generator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod()); generator.MarkLabel(endIfLabel); } } generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ret); dynamicBuilder.handler = (Load)method.CreateDelegate( typeof (Load)); return dynamicBuilder; } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection.Emit; using System.Data; using System.Reflection; namespace Pub.Class { public class IDataReaderEntityBuilder<Entity> { private static readonly MethodInfo getValueMethod = typeof(IDataRecord).GetMethod("get_Item", new Type[] { typeof(int) }); private static readonly MethodInfo isDBNullMethod = typeof(IDataRecord).GetMethod("IsDBNull", new Type[] { typeof(int) }); private delegate Entity Load(IDataRecord dataRecord); private Load handler; private IDataReaderEntityBuilder() { } public Entity Build(IDataRecord dataRecord) { return handler(dataRecord); } public static IDataReaderEntityBuilder<Entity> CreateBuilder(IDataRecord dataRecord) { IDataReaderEntityBuilder<Entity> dynamicBuilder = new IDataReaderEntityBuilder<Entity>(); DynamicMethod method = new DynamicMethod("IDataReaderDynamicCreateEntity", typeof(Entity), new Type[] { typeof(IDataRecord) }, typeof(Entity), true); ILGenerator generator = method.GetILGenerator(); LocalBuilder result = generator.DeclareLocal(typeof(Entity)); generator.Emit(OpCodes.Newobj, typeof(Entity).GetConstructor(Type.EmptyTypes)); generator.Emit(OpCodes.Stloc, result); for (int i = 0; i < dataRecord.FieldCount; i++) { PropertyInfo propertyInfo = typeof(Entity).GetProperty(dataRecord.GetName(i)); Label endIfLabel = generator.DefineLabel(); if (propertyInfo != null && propertyInfo.GetSetMethod() != null) { generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, i); generator.Emit(OpCodes.Callvirt, isDBNullMethod); generator.Emit(OpCodes.Brtrue, endIfLabel); generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, i); generator.Emit(OpCodes.Callvirt, getValueMethod); generator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); generator.Emit(OpCodes.Callvirt, propertyInfo.GetSetMethod()); generator.MarkLabel(endIfLabel); } } generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ret); dynamicBuilder.handler = (Load)method.CreateDelegate(typeof(Load)); return dynamicBuilder; } } }
