LinqToDB 源码分析——设计原理
我们知道实现了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 源码分析——设计原理的更多相关文章
- LinqToDB 源码分析——生成表达式树
当我们知道了Linq查询要用到的数据库信息之后.接下就是生成对应的表达式树.在前面的章节里面笔者就已经介绍过.生成表达式树是事实离不开IQueryable<T>接口.而处理表达式树离不开I ...
- Tomcat源码分析——请求原理分析(上)
前言 谈起Tomcat的诞生,最早可以追溯到1995年.近20年来,Tomcat始终是使用最广泛的Web服务器,由于其使用Java语言开发,所以广为Java程序员所熟悉.很多人早期的J2EE项目,由程 ...
- MyBatis 源码分析 - 缓存原理
1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 Redis 或 memcached 等缓存中间件,拦截大量奔向数据库的请求,减轻数据库压力.作为一个重要的组件,MyBatis 自然 ...
- Spring Boot 揭秘与实战 源码分析 - 工作原理剖析
文章目录 1. EnableAutoConfiguration 帮助我们做了什么 2. 配置参数类 – FreeMarkerProperties 3. 自动配置类 – FreeMarkerAutoCo ...
- Tomcat源码分析——请求原理分析(下)
前言 本文继续讲解TOMCAT的请求原理分析,建议朋友们阅读本文时首先阅读过<TOMCAT源码分析——请求原理分析(上)>和<TOMCAT源码分析——请求原理分析(中)>.在& ...
- Tomcat源码分析——请求原理分析(中)
前言 在<TOMCAT源码分析——请求原理分析(上)>一文中已经介绍了关于Tomcat7.0处理请求前作的初始化和准备工作,请读者在阅读本文前确保掌握<TOMCAT源码分析——请求原 ...
- wifidog源码分析 - wifidog原理 tiger
转:http://www.cnblogs.com/tolimit/p/4223644.html wifidog源码分析 - wifidog原理 wifidog是一个用于配合认证服务器实现无线网页认证功 ...
- Struts2 源码分析-----工作原理分析
请求过程 struts2 架构图如下图所示: 依照上图,我们可以看出一个请求在struts的处理大概有如下步骤: 1.客户端初始化一个指向Servlet容器(例如Tomcat)的请求: 2.这个请求经 ...
- LinqToDB 源码分析——生成与执行SQL语句
生成SQL语句的功能可以算是LinqToDB框架的最后一步.从上一章中我们可以知道处理完表达式树之后,相关生成SQL信息会被保存在一个叫SelectQuery类的实例.有了这个实例我们就可以生成对应的 ...
随机推荐
- C语言 · 矩阵乘法 · 算法训练
问题描述 输入两个矩阵,分别是m*s,s*n大小.输出两个矩阵相乘的结果. 输入格式 第一行,空格隔开的三个正整数m,s,n(均不超过200). 接下来m行,每行s个空格隔开的整数,表示矩阵A(i,j ...
- 23种设计模式--中介者模式-Mediator Pattern
一.中介者模式的介绍 中介者模式第一下想到的就是中介,房子中介,婚姻中介啊等等,当然笔者也希望来个婚姻中介给我介绍一个哈哈哈,,回归正题中介者模式分成中介者类和用户类,根据接口编程的方式我们再 ...
- scrapy 知乎用户信息爬虫
zhihu_spider 此项目的功能是爬取知乎用户信息以及人际拓扑关系,爬虫框架使用scrapy,数据存储使用mongo,下载这些数据感觉也没什么用,就当为大家学习scrapy提供一个例子吧.代码地 ...
- Git命令总结
本文转载自345大神.... 查看原文 先上个图形化界面GIT工具 SourceTree下载链接 windows版 1.8.3 & Mac版 2.2.4 链接: http://pan.baid ...
- Angular企业级开发(2)-搭建Angular开发环境
1.集成开发环境 个人或团队开发AngularJS项目时,有很多JavaScript编辑器可以选择.使用优秀的集成开发环境(Integrated Development Environment)能节省 ...
- 谈谈一些有趣的CSS题目(二)-- 从条纹边框的实现谈盒子模型
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- $ORACLE_HOME变量值末尾多“/”惹的祸
之前一直误以为$ORACLE_HOME变量的路径中末尾多写一个"/"不会有影响. 今天做实验时碰到一个情景,发现并不是这样. 环境:OEL 5.7 + Oracle 10.2.0. ...
- [原] KVM 虚拟化原理探究 —— 目录
KVM 虚拟化原理探究 -- 目录 标签(空格分隔): KVM KVM 虚拟化原理探究(1)- overview KVM 虚拟化原理探究(2)- QEMU启动过程 KVM 虚拟化原理探究(3)- CP ...
- UVa 122 Trees on the level
题目的意思: 输入很多个节点,包括路径和数值,但是不一定这些全部可以构成一棵树,问题就是判断所给的能否构成一棵树,且没有多余. 网上其他大神已经给出了题目意思:比如我一直很喜欢的小白菜又菜的博客 说一 ...
- 移动应用App测试与质量管理一
测试工程师 基于Html的WebApp测试, 现在一些移动App混Html5 HTML5性能测试 兼容性 整理后的脑图 测试招聘 弱化大量技术考察 看重看问题的高度 看重潜力 测试经验 质量管理 专项 ...