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

     

  • 相关阅读:
    021.day21 反射 Class类 反射常用操作
    020.day20 线程概述 多线程优缺点 线程的创建 线程常用方法 生命周期 多线程同步
    019.day19 缓冲流 对象流 标准输入输出流
    018.day18 map集合如何实现排序 File类 IO流 字节流 字符流 编码
    017.day17 Map接口 克隆 treeSet集合排重缺陷
    016.day16 HashSet TreeSet 比较器Comparable Comparator
    015.day15
    014.day14
    013.day13
    线程
  • 原文地址:https://www.cnblogs.com/cyq1162/p/2136911.html
Copyright © 2011-2022 走看看