我们知道实现了IQueryable<T>接口和IQueryProvider接口就可以使用Linq To SQL的功能。关于如何去实现的话,上一章也为我们引导了一个方向。LinqToDB框架也是顺着这个方向进行的。然而笔者对LinqToDB框架的作者真的很无语。如果有打开过LinqToDB框架源码的朋友,可能会发现很多代码都没有文字说明。这无疑给那些想要深入了解框架的人加大了前进力度。本来笔者以为只是没有相关代码说明不用怕。只要找到对应的文档应该没有什么大问题。于是笔者也跟很多人一样子——去作者的github上找。结果只有教大家如何使用。却对框架没有进行任何说明。笔者又想也许作者比较懒吧。可能只有在他的博客上才有相关的文档吧。结果笔者很失望——没有找到任何有帮助的东西。唉!为了能获得更多的资料笔者还购买了VPN。所以想要了解LinqToDB框架只有一个方式——硬着头皮啃代码。显然这种做法就是从代码中寻找作者的思路和理念。同时不可否认存在猜测上的错误。必竟作者的随意一段代码就有可能导至理解上的误导。希望读者们能够理解。

LinqToDB框架的原理


正如上面所讲的,LinqToDB框架也是按上一章中讲到的三个大至步骤进行的。所以我们的目标也变得很明确——了解LinqToDB框架是如何实现这三大步骤的。

1.实现Linq提供的IQueryable<T>接口和IQueryProvider接口。生成相关的表达式树。
2.把对应的表达式树转化生成对应数据库的SQL语句。并执行。
3.根据映射的信息,生成对应的集合类。

从上一章的例子中我们可以看到LinqToDB框架以DataContext类作为入口类。这一点显然跟Entity Framework一样子。都是以某个类做为上下文引动整个框架。如果你们看过github上的例子的话,就会发现笔者用的入口类跟作者不太一样子。作者用的是DataConnection类。事实上不管是DataConnection类还是DataContext类他们都继承了IDataContext接口。所以在使用上来讲,不会差太多。只是在笔者看来他们之间的职责却存在很大的差别。不过笔者还是不太明白作者这样子设计的目的。DataConnection类能做DataContext类的大部分事情,却又拥有自己独有的职责——负责存取当前数据库的信息。让笔者感觉DataConnection类在职责上有一点重复了。这也是为什么笔者认为DataContext类才是LinqToDB框架入口类。至少让笔者觉得DataContext类比较明确。

上面这张图片是描述了LinqToDB框架在查询时候的一个原理图。是笔者根据代码的运行路线整理出来的。主要的目地就是为了方便导引大家深入,少走一点弯路。我们知道要实现Linq查询很简单,就是上面的三个步骤。可是要实现这三个步骤的事情却很多。图片上只是显示主要核心类切口。可以说这三个步骤就是靠图片上的类进行工作的。

加载数据数库信息

LinqToDB框架并没有直接就将实现IQueryable<T>和IQueryProvider的类交出来。而是以上下文的思维方式间接性的引导出来。这也是合理的设计。必竟在生成表达式树和SQL语句之前,我们有必要知道数据库的相关信息。比如当前数据库是用什么——Sql Server还是MySql。而这个工作任务交给图中的DataConnection。这味意着LinqToDB框架在进入上面所讲的第一步的时候,就已经知道数据库的信息了。但是作者并没有直接性的设置数据库的信息。而是通过IDataProvider接口实例来提供。这样子更加区别出DataContext类只是用于引导的职责。如果你们使用过增删改的话,你们可能会觉得不对。他不是可以会增删改吗?事实上如果你们用心点的话,就会现他们都是静态扩展方法。

生成表达式树

通过DataContext类我们就可以拿到我们的集合表(这里的集合表是指实现ITable接口的实例)。ITable接口作用跟Entity Framework的IDbSet接口很相近。从代码中我们可能看到他来自于IExpressionQuery接口。相信大家看到名字就明白IExpressionQuery接口的实现类就是图片中的ExpressionQuery类。这个时候上面说的第一步工作开始进行了。ExpressionQuery类就是对应的实现IQueryable<T>接口和IQueryProvider接口的类。当然,LinqToDB框架用的是IQueryable<T>接口的子接口——IOrderedQueryable<T>。生成表达式树的工作也在这里进展开始了。

执行数据库

要实现Linq查询的功能主要难点在如何去处理表达式树,在通过表达式树生成对应的T-SQL。LinqToDB框架通过一个核心类Query来作中间过度。笔者喜欢把他叫中间者。作者在设计用到Query类时候,并不是把他直接实例出来。而是通过ExpressionBuilder类进行进一步的加工,把相关的信息分配来Query类实例,在返回Query类实例。那么对于ExpressionBuilder类的职责笔者用一俩句话是很难说清楚。这里只能大概讲他是用于处理表达式树的。其中不得不用到一个叫SelectQuery类的。这个类很重要。他会参与最后生成T-SQL工作里面去。笔者想说通过ExpressionBuilder类加工之后,对应的是查询还是增删改都会记录在SelectQuery类实例里面。就相当于生成T-SQL的信息都存放在SelectQuery类实例里面。

Query类的工作职责比较复杂。当经历过处理表达式树的过程之后,Query类就具备生成T-SQL的能力了。为什么这样子讲呢?这个时候Query类拥有生成T-SQL的SelectQuery类实例和结果集的映射信息MapInfo类实例。所以生成T-SQL也只是一个时间问题。在生成T-SQL的这个过程看起来简单,事实上却有很多细节要处理。作者让LinqToDB框架通过DataConnection类去调用BasicSqlBuilder类的子类来处理生成T-SQL。当然这一个过程里面离不开SelectQuery类。只是作者并不是直接提交T-SQL,而是生成一个叫PreparedQuery类实例。PreparedQuery类用于存放执行数据库的信息。这也是最后一步了。通过PreparedQuery类实例生成XxxCommand类执行数据库。在通过MapInfo类实例转化为对应的集合数据。

结束语


好了。对于LinqToDB框架的原理笔者就介绍在这里。本系列的后面章节也是依据本章的思路进行的。看看作者是什么样子设计LinqToDB框架的。又有什么值得我们去学习的。

LinqToDB 源码分析——设计原理的更多相关文章

  1. LinqToDB 源码分析——生成表达式树

    当我们知道了Linq查询要用到的数据库信息之后.接下就是生成对应的表达式树.在前面的章节里面笔者就已经介绍过.生成表达式树是事实离不开IQueryable<T>接口.而处理表达式树离不开I ...

  2. Tomcat源码分析——请求原理分析(上)

    前言 谈起Tomcat的诞生,最早可以追溯到1995年.近20年来,Tomcat始终是使用最广泛的Web服务器,由于其使用Java语言开发,所以广为Java程序员所熟悉.很多人早期的J2EE项目,由程 ...

  3. MyBatis 源码分析 - 缓存原理

    1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 Redis 或 memcached 等缓存中间件,拦截大量奔向数据库的请求,减轻数据库压力.作为一个重要的组件,MyBatis 自然 ...

  4. Spring Boot 揭秘与实战 源码分析 - 工作原理剖析

    文章目录 1. EnableAutoConfiguration 帮助我们做了什么 2. 配置参数类 – FreeMarkerProperties 3. 自动配置类 – FreeMarkerAutoCo ...

  5. Tomcat源码分析——请求原理分析(下)

    前言 本文继续讲解TOMCAT的请求原理分析,建议朋友们阅读本文时首先阅读过<TOMCAT源码分析——请求原理分析(上)>和<TOMCAT源码分析——请求原理分析(中)>.在& ...

  6. Tomcat源码分析——请求原理分析(中)

    前言 在<TOMCAT源码分析——请求原理分析(上)>一文中已经介绍了关于Tomcat7.0处理请求前作的初始化和准备工作,请读者在阅读本文前确保掌握<TOMCAT源码分析——请求原 ...

  7. wifidog源码分析 - wifidog原理 tiger

    转:http://www.cnblogs.com/tolimit/p/4223644.html wifidog源码分析 - wifidog原理 wifidog是一个用于配合认证服务器实现无线网页认证功 ...

  8. Struts2 源码分析-----工作原理分析

    请求过程 struts2 架构图如下图所示: 依照上图,我们可以看出一个请求在struts的处理大概有如下步骤: 1.客户端初始化一个指向Servlet容器(例如Tomcat)的请求: 2.这个请求经 ...

  9. LinqToDB 源码分析——生成与执行SQL语句

    生成SQL语句的功能可以算是LinqToDB框架的最后一步.从上一章中我们可以知道处理完表达式树之后,相关生成SQL信息会被保存在一个叫SelectQuery类的实例.有了这个实例我们就可以生成对应的 ...

随机推荐

  1. .NET平台开源项目速览(18)C#平台JSON实体类生成器JSON C# Class Generator

    去年,我在一篇文章用原始方法解析复杂字符串,json一定要用JsonMapper么?中介绍了简单的JSON解析的问题,那种方法在当时的环境是非常方便的,因为不需要生成实体类,结构很容易解析.但随着业务 ...

  2. 从零开始编写自己的C#框架(28)——建模、架构与框架

    文章写到这里,我一直在犹豫是继续写针对中小型框架的设计还是写些框架设计上的进阶方面的内容?对于中小型系统来说,只要将前面的内容进行一下细化,写上二三十章具体开发上的细节,来说明这个通用框架怎么开发的就 ...

  3. 基于AOP的MVC拦截异常让代码更优美

    与asp.net 打交道很多年,如今天微软的优秀框架越来越多,其中微软在基于mvc的思想架构,也推出了自己的一套asp.net mvc 框架,如果你亲身体验过它,会情不自禁的说‘漂亮’.回过头来,‘漂 ...

  4. Android公共title的应用

    我们在开发Android应用中,写每一个页面的时候都会建一个title,不是写一个LinearLayout就是写一个RelativeLayout,久而久之就会觉得这样繁琐,尤其几个页面是只是标题不一样 ...

  5. 原生js+css3实现图片自动切换,图片轮播

    运用CSS3transition及opacity属性 制作图片轮播动画 自己这两天根据用js来控制触发CSS3中transition属性,从而写出来的以CSS3动画为基础,js控制过程的图片轮播 运用 ...

  6. RSA算法

    RSA.h #ifndef _RSA_H #define _RSA_H #include<stdio.h> #include<iostream> #include<mat ...

  7. 自己实现简单Spring Ioc

    IoC则是一种 软件设计模式,简单来说Spring通过工厂+反射来实现IoC. 原理简单说明: 其实就是通过解析xml文件,通过反射创建出我们所需要的bean,再将这些bean挨个放到集合中,然后对外 ...

  8. ASP.NET MVC 5 系列 学习笔记 目录 (持续更新...)

    前言: 记得当初培训的时候,学习的还是ASP.NET,现在回想一下,图片水印.统计人数.过滤器....HttpHandler是多么的经典! 不过后来接触到了MVC,便立马爱上了它.Model-View ...

  9. [AlwaysOn Availability Groups]健康模型 Part 1——概述

    健康模型概述 在成功部署AG之后,跟踪和维护健康状况是很重要的. 1.AG健康模型概述 AG的健康模型是基于策略管理(Policy Based Management PBM)的.如果不熟悉这个特性,可 ...

  10. Linux程序包管理之rpm

    rpm简介 rpm( Red Hat Package Manager )是一个开放的软件包管理系统.它工作于Red Hat Linux及其他Linux系统,成为Linux中公认的软件包管理标准. rp ...