zoukankan      html  css  js  c++  java
  • 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
        }
    }

     

    页面效果:

     

     

    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, nullnew 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, nullnew 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

     

  • 相关阅读:
    吴裕雄--天生自然 PHP开发学习:数组
    吴裕雄--天生自然 JAVASCRIPT开发学习:测试 jQuery
    【t065】最敏捷的机器人
    【t079】火星上的加法运算
    【t053】整数去位
    【9604】纪念品分组
    【心情】bjdldrz
    【9601】零件分组
    【9916】编辑距离
    【38.24%】【POJ 1201】Intervals
  • 原文地址:https://www.cnblogs.com/cyq1162/p/2136911.html
Copyright © 2011-2022 走看看