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生成实体
///
///
///
///
publicstaticListToList(thisDataTabledataTable)whereT:class,new()
{
if(dataTable==null||dataTable.Rows.Count<=0)thrownewArgumentNullException("dataTable","当前对象为null无法生成表达式树");
Funcfunc=dataTable.Rows[0].ToExpression();
Listcollection=newList(dataTable.Rows.Count);
foreach(DataRowdrindataTable.Rows)
{
collection.Add(func(dr));
}
returncollection;
}
///
///生成表达式
///
///
///
///
publicstaticFuncToExpression(thisDataRowdataRow)whereT:class,new()
{
if(dataRow==null)thrownewArgumentNullException("dataRow","当前对象为null无法转换成实体");
ParameterExpressionparameter=Expression.Parameter(typeof(DataRow),"dr");
Listbinds=newList();
for(inti=0;i>(init,parameter).Compile();
}
#endregion
///
///生成lambda表达式
///
///
///
///
publicstaticFuncToExpression(thisSqlDataReaderreader)whereT:class,new()
{
if(reader==null||reader.IsClosed||!reader.HasRows)thrownewArgumentException("reader","当前对象无效");
ParameterExpressionparameter=Expression.Parameter(typeof(SqlDataReader),"reader");
Listbinds=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;
Listusrs=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表达式的地方出错,所以先将现在的
方案记录下来。