您的位置:首页 > 其它

CYQ.Data V4.5.5 版本发布[顺带开源Emit编写的快速反射转实体类FastToT类]

2012-03-09 00:00 465 查看
前言:

继上一版本:CYQ.Data 数据框架 版本发布 V4.5,刷的一下又三个多月了,

进一步的说,从 CYQ.Data V4.5的发布到现在,是半年多了,今天,终于得发布新小版本了。

由于上一版本过于稳定,导致此版本无bug修正项,但是新增了几个重要的性能优化功能。

本版本新增加的功能预览



[b]1:优化Access、SQLite数据库链接,以{0}代表根目录


好处:可以配置多个数据库链接,示例如:秋色园QBlog同时用了N个access数据库。

2:MAction增加指定列的查询功能:SetSelectColumns

好处:查询时可以指定列名,减少传输量。

3:增加AppDebug类,可以全局输出执行过的SQL语句

好处:随时掌控并打印页面SQL,直接分析和优化SQL语句

4:增加FastToT的Emit类,提升大数据量时从MDataTable转List<T>的性能

好处:在返回数据量较大转实体时,可以利用Emit加快速度,提升性能。

5:关闭默认mssql/oracle的事务开启

好处:事务有需要就打开,默认不打开。

如需要兼容V4.5及以前版本的事务,可使用配置项兼容:<add key="TransationDefaultOpen" value="true"> </add>

6:XmlHelper更名为XHtmlAction

其它:增加的配置项:

OpenDebugInfo:true/false,是否开启调试SQL语句记录,开发时打开,运行时可关闭。

RecordSqlLongQueryTime:N(单位毫秒),运行时设置,记录执行时间长的SQL语句,可以针对性分析与优化。

AppDebugFilterTime:N(单位毫秒),AppDebug可以输出页面SQL,通过此项可以过滤。

[/b]

下面进行详细的解说

1:优化Access、SQLite数据库链接,以{0}代表根目录

示例:



[b]<connectionStrings>
<add name="Conn" connectionString="Data Source={0}App_Data\qblog.db;failifmissing=false" providerName="System.Data.SQLite" />
</connectionStrings>

[/b]

2:MAction增加指定列的查询功能:SetSelectColumns

示例:[包含:查询,分页,绑定]



protected void BindData()

{

int count;

using (MAction action = new MAction(TableNames.Blog_Class))

{

action.SetSelectColumns(selectColumns);//指定列

action.Select(Pager1.PageIndex, Pager1.PageSize, string.Empty, out count).Bind(gvClass);

Pager1.Count = count;

Pager1.BindName = "BindData";

}

}


3:增加AppDebug类,可以全局输出执行过的SQL语句

示例:[在页面基类里,轻松处理一下即可]

public class PageBase:System.Web.UI.Page

{

protected override void OnInit(EventArgs e)

{

AppDebug.Start();//开启记录页面的SQL

base.OnInit(e);

}

protected override void OnPreRenderComplete(EventArgs e)

{

base.OnPreRenderComplete(e);

Response.Write(AppDebug.Info);//输出记录页面的SQL

AppDebug.Stop();//停止记录页面的SQL

}

}

页面效果:



4:增加FastToT的Emit类,提升大数据量时从MDataTable转List<T>的性能

这里直接放上我研究N天的源码,不过能看懂的估计也毛毛无几,能用上的直接拿去用了:

using
System;

using
System.Collections.Generic;

using
System.Text;

using
System.Reflection.Emit;

using
System.Reflection;

using
CYQ.Data.Table;

namespace
CYQ.Data.Tool
{

///

<summary>

///
快速转换类[数据量越大[估约500条起],性能越高]

///

</summary>

internal

class
FastToT
<
T
>

{

public

delegate
T EmitHandle(MDataRow row);

///

<summary>

///
构建一个ORM实体转换器

///

</summary>

///

<typeparam name="T">
转换的目标类型
</typeparam>

///

<param name="schema">
表数据架构
</param>

public

static
EmitHandle Create(MDataTable schema)
{
Type tType
=

typeof
(T);
Type rowType
=

typeof
(MDataRow);
DynamicMethod method
=

new
DynamicMethod(
"
RowToT
"
, tType,
new
Type[] { rowType }, tType);

MethodInfo getValue
=
rowType.GetMethod(
"
GetItemValue
"
, BindingFlags.Instance
|
BindingFlags.Public
|
BindingFlags.NonPublic,
null
,
new
Type[] {
typeof
(
int
) },
null
);

ILGenerator gen
=
method.GetILGenerator();

gen.DeclareLocal(tType);
gen.DeclareLocal(
typeof
(
object
));
gen.DeclareLocal(
typeof
(
bool
));

gen.Emit(OpCodes.Newobj, tType.GetConstructor(BindingFlags.Instance
|
BindingFlags.Public
|
BindingFlags.NonPublic,
null
,
new
Type[] { },
null
));
gen.Emit(OpCodes.Stloc_0);

int
ordinal
=

-
1
;

foreach
(FieldInfo field
in
tType.GetFields(BindingFlags.Instance
|
BindingFlags.NonPublic
|
BindingFlags.Public))
{

string
fieldName
=
field.Name.TrimStart(
'
_
'
);
ordinal
=
schema.GetOrdinal(fieldName);

if
(ordinal
>

-
1
)
{
Label retFalse
=
gen.DefineLabel();
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldc_I4, ordinal);
gen.Emit(OpCodes.Call, getValue);
gen.Emit(OpCodes.Stloc_1);

gen.Emit(OpCodes.Ldloc_1);
gen.Emit(OpCodes.Ldnull);
gen.Emit(OpCodes.Ceq);
gen.Emit(OpCodes.Stloc_2);
gen.Emit(OpCodes.Ldloc_2);

gen.Emit(OpCodes.Brtrue_S, retFalse);
//
为null值,跳过

gen.Emit(OpCodes.Ldloc_0);
gen.Emit(OpCodes.Ldloc_1);
EmitCastObj(gen, field.FieldType);
gen.Emit(OpCodes.Stfld, field);

gen.MarkLabel(retFalse);
//
继续下一个循环

}
}

gen.Emit(OpCodes.Ldloc_0);
gen.Emit(OpCodes.Ret);

return
method.CreateDelegate(
typeof
(EmitHandle))
as
EmitHandle;
}

private

static

void
EmitCastObj(ILGenerator il, Type targetType)
{

if
(targetType.IsValueType)
{
il.Emit(OpCodes.Unbox_Any, targetType);
}

else

{
il.Emit(OpCodes.Castclass, targetType);
}
}
}
}

其它几点的示例,写成了示例项目:

示例解决方案:



完整的示例页面:



最后:

CYQ.Data 数据框架主页:http://www.cyqdata.com/cyqdata

CYQ.Data 数据框架下载(包括示例):http://www.cyqdata.com/download/article-detail-426

原文链接:
http://www.cnblogs.com/cyq1162/archive/2011/08/13/2136911.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐