IDataReaderDataTable扩展ToList 改进版,反射速度慢的惊人!

    技术2026-09-28  6

    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; } } }
    最新回复(0)