说知识那么多无法如何都看源码和理解原理吧【澳门皇冠官网app】

三.Dapper.NET扩展:

 
 这一部分是顺水人情,该片段代码是对Dapper.NET代码做一封装,能够临近于操作别的ORM的点子,须要者能够自取,就毫无四处去找这几个事物了。

 
 Dapper.NET扩大方法包

    Dapper包

 
 方今在三个群里碰着一人说的话,在此间不再赘言,大致意思正是上下一心各个掌握各个懂,面试时各类装X各类吊,自个儿真诚的求教了一下他,问他是或不是懂那几个事物的尾巴部分原理,是还是不是领会过底层源码,能无法依照实际意况修改源码,哪个人知被她戏弄说说大话,说知识那么多不能够怎么都看源码和领悟原理吧。然则我只想说,那但是你和睦说自身掌握,难道掌握的框架不应该通晓源码和公理吗?难道掌握正是只略知一二怎么归纳的采纳吗?难道是本人拉家常的主意不对?

一.Dapper.NET概述:

 
项目开荒时,大家都是要求思念项目标本领架构,越发是对数据库底层的虚构相当多。今后对于数据库的拜见有ADO.NET,EF,Dapper.NET等等,分裂的场所会有例外的选料,钻探的时候都会提及“xx很牛逼,xx功用相当高”等等,由此可见必要干一场,才算我们开过会。(非常多时候,在开会前项目选什么技能一度定了,可是不开个会就展现做事不严峻…),在采纳Dapper.NET时,有人讲到Dapper.NET功效高,很牛逼,也不驾驭极其新人说了一句“为何Dapper.NET作用高?”

   好尴尬…

   Dapper.NET是一个轻巧易行的ORM,特意从SQL查询结果中连忙转移对象。Dapper.Net援助推行sql查询并将其结果映射到强类型列表或动态目的列表。Dapper.Net缓存各样查询的音信。这种周密的缓存有利于从概略上两倍于LINQ到SQL的查询生成对象。当前缓存由四个ConcurrentDictionary对象管理,它们没有被免去。

 
 Dapper.Net通过扩大方法将七个映射函数增添到IDbConnection接口,那三个函数都命名叫ExecuteMapperQuery。第三个映射结果是三个强类型列表,而第一个映射结果是一个动态指标列表。ExecuteMapperCommand施行何况不回来结果集。全体三个法子都将参数接受为无名类,在那之中属性值映射到同名的SQL参数。

   Dapper.Net意在仅管理结果集到目的映射。它不管理对象时期的关系,它不会自动生成任何项指标SQL查询。

 
 年少时,为什么不为本人的指望去激昂一遍啊?纵使鱼溃鸟离,也不悔有那一年少轻狂。感叹较多,这两天业务也比比较多,博客也相当少更新了,毕竟每种人都亟需为和睦的生活去努力。

四.总结:

   
那篇博文是自个儿硬着头皮写的,因为基本未有类似的稿子,连仿照效法的资料都尚未,最多的正是调用代码的demo,对于原理和后面部分源码分析基本未有,在这里就用这篇博文引出大神对其完善的剖释。希望对大家有一点点帮忙,也算是尽力了。

   在那边大约介绍一下其规律  

 
 近些日子遇见五个难题,那便是关于Dapper.NET的某个主题材料,Dapper.NET的作用为什么相当高?该器件的运作规律是哪些?说句实话,作者找了非常久都未有意识类似的文章,不知道是或不是本身的搜素格局不对,犹盼望发现类似好的篇章的相爱的人发给本身看看,知识在于分享嘛,不要吝啬你的文化,让我们共同前进吧。

二.Dapper.NET原理深入分析:

 
 通过Dapper.NET的源码大家得以窥见其重大是“总部方法和总局类”,有关于“根据地方法和总局类”的学问能够看那篇博客:http://www.cnblogs.com/pengze0902/p/6369541.html。Dapper.Net也如果连接已开采并预备稳当,Dapper.NET通过对IDbConnection接口进行扩张。在Dapper.NET对数据库连接成功后,能够进行相关的操作,接下去大家就来看一下那些操作的贯彻格局。

   1.Query()方法:

Query<T>(this IDbConnection cnn, string sql, object param = null, 
         IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null

 
 改方法表示施行查询,再次回到按T输入的数码。该办法是Query()方法的泛型方法,有7个参数,第三个参数为IDbConnection增加类,表示对IDbConnection接口举行扩大,该方法应用了可选参数,提升措施的扩张性。在Query方法的兑现中,有一个CommandDefinition类,用来表示sql操作的基本点方面。在此类下有二个GetInit()方法。

   2.GetInit()方法:

   
大家都清楚Dapper.NET通过Emit反射IDataReader的种类队列,来极快的获得和产生对象。GetInit()方法是多个静态方法,该情势的“Type
commandType”参数表示连接关联的Command对象,重临叁个Action<IDbCommand>委托。

   大家就实际看一下是何等通过Emit反射IDataReader的队列队列的。

if (SqlMapper.Link<Type, Action<IDbCommand>>.TryGet(commandInitCache, commandType, out action)){ return action; }

   Link<TKey,
电视alue>是八个泛型分部类,那是一个微缓存,查看是还是不是留存叁个Action<IDbCommand>的信托。

var bindByName = GetBasicPropertySetter(commandType, "BindByName", typeof(bool));
var initialLongFetchSize = GetBasicPropertySetter(commandType, "InitialLONGFetchSize", typeof(int));

 
 以上七个操作首要猎取BindByName和InitialLONGFetchSize的获取基本属性设置。

    if (bindByName != null || initialLongFetchSize != null)
            {
                var method = new DynamicMethod(commandType.Name + "_init", null, new Type[] { typeof(IDbCommand) });
                var il = method.GetILGenerator();
                if (bindByName != null)
                {
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Castclass, commandType);
                    il.Emit(OpCodes.Ldc_I4_1);
                    il.EmitCall(OpCodes.Callvirt, bindByName, null);
                }
                if (initialLongFetchSize != null)
                {
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Castclass, commandType);
                    il.Emit(OpCodes.Ldc_I4_M1);
                    il.EmitCall(OpCodes.Callvirt, initialLongFetchSize, null);
                }
                il.Emit(OpCodes.Ret);
                action = (Action<IDbCommand>)method.CreateDelegate(typeof(Action<IDbCommand>));
            }

 
 这一步是该操作的主干部分,利用Emit反射操作。根据上一步获取的呼应名称的大旨性子设置,采取DynamicMethod对象,定义和象征二个方可编写翻译,执行和抛弃的动态方法。遗弃的主意可用于垃圾回收。调用该指标的GetILGenerator方法,重返方法的Microsoft中间语言(MSIL)生成器,默许的MSIL流大小为64字节。剖断基脾品质设置不为空后,调用ILGenerator类的Emit方法,Emit()将钦命的授命放在指令流上,该办法接收八个IL流。EmitCall()将 call 或 callvirt 指令置于
Microsoft 中间语言 (MSIL)
流,以调用varargs 方法。我们看看OpCodes类,该类描述中间语言 (IL)
指令。CreateDelegate()完结动态方法并创立叁个可用来实践它的嘱托。

   通过以上的反射操作创设好靶子后,就能随之推行相应的数据库操作。

 3.QueryImpl():

 private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefinition command, Type effectiveType)
        {
            object param = command.Parameters;
            var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param == null ? null : param.GetType(), null);
            var info = GetCacheInfo(identity, param, command.AddToCache);
            IDbCommand cmd = null;
            IDataReader reader = null;
            bool wasClosed = cnn.State == ConnectionState.Closed;
            try
            {
                cmd = command.SetupCommand(cnn, info.ParamReader);
                if (wasClosed) cnn.Open();
                reader = cmd.ExecuteReader(wasClosed ? CommandBehavior.CloseConnection | CommandBehavior.SequentialAccess : CommandBehavior.SequentialAccess);
                wasClosed = false; 
                var tuple = info.Deserializer;
                int hash = GetColumnHash(reader);
                if (tuple.Func == null || tuple.Hash != hash)
                {
                    if (reader.FieldCount == 0) 
                        yield break;
                    tuple = info.Deserializer = new DeserializerState(hash, GetDeserializer(effectiveType, reader, 0, -1, false));
                    if (command.AddToCache) SetQueryCache(identity, info);
                }
                var func = tuple.Func;
                var convertToType = Nullable.GetUnderlyingType(effectiveType) ?? effectiveType;
                while (reader.Read())
                {
                    object val = func(reader);
                    if (val == null || val is T)
                    {
                        yield return (T)val;
                    }
                    else
                    {
                        yield return (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture);
                    }
                }
                while (reader.NextResult()) { }
                reader.Dispose();
                reader = null;
                command.OnCompleted();
            }
            finally
            {
                if (reader != null)
                {
                    if (!reader.IsClosed) try { cmd.Cancel(); }
                        catch { /* don't spoil the existing exception */ }
                    reader.Dispose();
                }
                if (wasClosed) cnn.Close();
                if (cmd != null) cmd.Dispose();
            }
        }

   
该格局为实践查询操作的基本措施,通过CommandDefinition类的有关操作后,获取到对应的目的后,实施这一步操作。该措施是IDbConnection的强大方法,CommandDefinition表示sql的相关操作对象,Type表示传入的三个使得的连串。Identity对象表示Dapper中的缓存查询的标记,该类是两个总局类,能够对其进展相应的恢弘。GetCacheInfo()获取缓存音信。

相关文章