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

前言:

 

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

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

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

 

本版本新增加的功能预览

 

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,通过此项可以过滤。

 

下面进行详细的解说

 

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

示例:

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

 

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
    }
}

 

页面效果:

 

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

 

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 V4.5.5 版本发布[顺带开源Emit编写的快速反射转实体类FastToT类]_第2张图片

 

完整的示例页面:

 

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

 

最后:

 

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

你可能感兴趣的:(CYQ.Data V4.5.5 版本发布[顺带开源Emit编写的快速反射转实体类FastToT类])