SqlDataReader生成动态Lambda表达式
上一扁使用动态lambda表达式来将DataTable转换成实体,比直接用反射快了不少。主要是首行转换的时候动态生成了委托。
后面的转换都是直接调用委托,省去了多次用反射带来的性能损失。
今天在对SqlServer返回的流对象SqlDataReader进行处理,也采用动态生成Lambda表达式的方式转换实体。
先上一版代码
usingSystem; usingSystem.Collections.Generic; usingSystem.Data; usingSystem.Data.Common; usingSystem.Data.SqlClient; usingSystem.Linq; usingSystem.Linq.Expressions; usingSystem.Reflection; usingSystem.Text; usingSystem.Threading.Tasks; namespaceDemo1 { publicstaticclassEntityConverter { #region //////DataTable生成实体 /// ////// /// publicstaticList ToList (thisDataTabledataTable)whereT:class,new() { if(dataTable==null||dataTable.Rows.Count<=0)thrownewArgumentNullException("dataTable","当前对象为null无法生成表达式树"); Func func=dataTable.Rows[0].ToExpression (); List collection=newList (dataTable.Rows.Count); foreach(DataRowdrindataTable.Rows) { collection.Add(func(dr)); } returncollection; } /// ///生成表达式 /// ////// /// publicstaticFunc ToExpression (thisDataRowdataRow)whereT:class,new() { if(dataRow==null)thrownewArgumentNullException("dataRow","当前对象为null无法转换成实体"); ParameterExpressionparameter=Expression.Parameter(typeof(DataRow),"dr"); List binds=newList (); for(inti=0;i >(init,parameter).Compile(); } #endregion /// ///生成lambda表达式 /// ////// /// publicstaticFunc ToExpression (thisSqlDataReaderreader)whereT:class,new() { if(reader==null||reader.IsClosed||!reader.HasRows)thrownewArgumentException("reader","当前对象无效"); ParameterExpressionparameter=Expression.Parameter(typeof(SqlDataReader),"reader"); List binds=newList (); for(inti=0;i >(init,parameter).Compile(); } } }
在上一篇的基础上增加了SqlDataReader的扩展方法
以下代码是调用
usingSystem; usingSystem.Collections.Generic; usingSystem.Data; usingSystem.Data.Common; usingSystem.Data.SqlClient; usingSystem.Diagnostics; usingSystem.Linq; usingSystem.Reflection; usingSystem.Text; usingSystem.Threading.Tasks; namespaceDemo1 { classProgram { staticvoidMain(string[]args) { StringconString="DataSource=.;InitialCatalog=master;IntegratedSecurity=true;"; Funcfunc=null; List usrs=newList (); using(SqlDataReaderreader=GetReader(conString,"selectobject_id'ID',name'Name'fromsys.objects",CommandType.Text,null)) { while(reader.Read()) { if(func==null) { func=reader.ToExpression (); } Usrusr=func(reader); usrs.Add(usr); } } usrs.Clear(); Console.ReadKey(); } publicstaticSqlDataReaderGetReader(StringconString,Stringsql,CommandTypetype,paramsSqlParameter[]pms) { SqlConnectionconn=newSqlConnection(conString); SqlCommandcmd=newSqlCommand(sql,conn); cmd.CommandType=type; if(pms!=null&&pms.Count()>0) { cmd.Parameters.AddRange(pms); } conn.Open(); returncmd.ExecuteReader(CommandBehavior.CloseConnection); } } classUsr { publicInt32ID{get;set;} publicStringName{get;set;} } }
目前只能处理sqlserver返回的对象,处理其它数据库本来是想增加DbDataReader的扩展方法,但发现动态生成lambda表达式的地方出错,所以先将现在的
方案记录下来。