DbUtility Ex

时间:2023-03-08 15:26:07
DbUtility Ex

扩展 DbUtility (1)

2014-05-22 21:48 by Ivony..., 234 阅读, 3 评论, 收藏编辑

本文原始路径: https://www.zybuluo.com/Ivony/note/14074

前言

DbUtility v3 是一个开源的轻量级数据库访问框架,源代码通过 Apache 协议发布,可以用于商业用途。最新的版本可以通过 NuGet 进行下载,项目及源代码下载地址:

https://github.com/Ivony/DbUtility

DbUtility 第一个版本公开于七年前,关于 DbUtility 的历史和 DbUtility 的使用,请参考下面这篇博客:

http://www.cnblogs.com/Ivony/p/3659746.html 
https://www.zybuluo.com/Ivony/note/8277

作为一个开源项目,DbUtility 不仅仅致力于帮助大家简化数据库访问,也非常欢迎和期待大家的共同参与,不论是提交 Bug 或者单元测试,或是新的特性需求,以及自己动手为 DbUtility 增加更多有趣的功能,都是参与开源项目的方式。这篇文章面向所有有志于为 DbUtility 增添自定义功能的程序员,介绍 DbUtility 的扩展架构。

基本结构

DbUtility v3 相较于之前版本的最大区别,也是 DbUtility v3 傲视其他轻量级数据库访问框架的地方,就是其优良的扩展架构。正如之前的介绍所述,DbUtility 将一个数据库查询分为三个部分:

  • 查询执行器
  • 查询构建器
  • 结果构建器

这三个部分各有一个关键的接口,分别为:

  • IDbExecutor where T : IDbQuery 定义某种类型查询的查询执行器。
  • IDbQuery 定义特定的数据库查询
  • IDbExecuteContext 定义数据库查询执行上下文,其中包括 DataReader 对象。

譬如说 SqlDbUtility 类型便是面向 SQL Server 数据库的查询执行器实现类型,其声明为:

public class SqlDbUtility :
IAsyncDbExecutor<ParameterizedQuery>,
IAsyncDbExecutor<StoredProcedureQuery>,
IDbTransactionProvider<SqlDbUtility>

IAsyncDbExecutor 是 IDbExecutor 的异步版本,表示可以异步执行指定类型的查询。可以看出来SqlDbUtility实现了两个查询执行器接口,分别是 IAsyncDbExecutor<ParameterizedQuery> 和 IAsyncDbExecutor<StoredProcedureQuery> 这表示这个类型的对象既可以执行 ParameterizedQuery 类型(参数化查询)的查询,也能执行 StoredProcedureQuery 类型(存储过程)的查询。

扩展查询构建器

接下来我们尝试扩展一个查询构建方法,就像T( "SELECT * FROM Users" )一样。

假定我们经常会遇到一个场景,需要获取某个表的所有数据,如果直接使用T来构建参数化查询,则所需写的SQL语句很多: SELECT * FROM TableName ,我们希望简化为 DT( "TableName" ) 的形式,该如何做呢?

首先我们要确定我们是否需要构建一种新的查询类型,因为构建新的查询类型,需要同时修改查询执行器,在本例中暂不涉及这么深入的问题。我们假定暂且借用参数化查询对象,只是简化其生成代码。

那么首先我们需要了解的一个事实是,所有的查询构建方法其实都是扩展方法,针对特定的查询执行器,对其进行扩展。如果我们生成的是一个参数化查询,那么我们需要一个参数化查询执行器才能执行,所以我们要针对参数化查询执行器进行扩展。首先新建一个扩展方法所需的静态类型:

public static class MyExtensions
{ }

值得注意的是定义扩展方法的类型必须是静态类型。

然后我们添加一个扩展方法,因为我们最终生成的查询类型是参数化查询,所以我们需要对可以执行参数化查询的对象进行扩展,像这样:

public static void DT( this IDbExecutor<ParameterizedQuery> executor, string tableName )
{
throw new NotImplementedException();
}

请注意我这边的返回值类型还没有填写,因为这里涉及到另一个问题,单纯的查询对象是不能被执行的,为了达到 db.DT( "Users" ).ExecuteDataTable() 这样的效果,我们需要把查询对象和查询执行器捆绑起来,这个捆绑后的对象的类型为 IDbExecutableQuery (意为可执行的查询),所以我们需要把返回值设置为 IDbExecutableQuery 类型:

public static IDbExecutableQuery DT( this IDbExecutor<ParameterizedQuery> executor, string tableName )
{
throw new NotImplementedException();
}

DbUtility 已经为我们提供了现成的 IDbExecutableQuery 的实现,即 DbExecutableQuery<T> 类型,我们只需要构建一个查询对象,再连同查询执行器一起调用这个类型的构造函数即可:

public static IDbExecutableQuery DT( this IDbExecutor<ParameterizedQuery> executor, string tableName )
{
ParameterizedQuery query = null;
return new DbExecutableQuery<ParameterizedQuery>( executor, query );
}

最后,我们需要构建一个参数化查询对象,参数化查询对象作为基础查询对象,有很多种方式来构建,最常见的就是利用模板来构建,如果直接调用 db.T 方法,事实上构建出来的是 DbExecutableQuery<ParameterizedQuery> 类型的对象,好在系统提供了一个静态类型 Db 来对这些常见任务提供支持:

public static IDbExecutableQuery DT( this IDbExecutor<ParameterizedQuery> executor, string tableName )
{
ParameterizedQuery query = Db.T( "SELECT * FROM " + tableName );
return new DbExecutableQuery<ParameterizedQuery>( executor, query );
}

至此,我们的第一个扩展就已经完成了,马上来试一下:

  var db = SqlDbUtility.Create( "Database" );
var data = db.DT( "Users" ).ExecuteDataTable();

尾声

事实上你知道吗,db.T 这个方法,其内部实现就是这样的 
以下摘自DbUtility v3源代码:

DbUtility Ex
public static DbExecutableQuery<ParameterizedQuery> Template( this IDbExecutor<ParameterizedQuery> executor, string template, params object[] parameters )
{
return new DbExecutableQuery<ParameterizedQuery>( executor, TemplateParser.ParseTemplate( template, parameters ) );
}
public static DbExecutableQuery<ParameterizedQuery> T( this IDbExecutor<ParameterizedQuery> executor, string template, params object[] parameters )
{
return Template( executor, template, parameters );
}
DbUtility Ex

接下来,我们把这个方法再进一步扩展,我们希望用户调用这个方法的时候,不再返回一个可执行的查询对象,而是直接执行查询,并将 DataTable 返回就好了,相信聪明的你应该很快就能想到怎样写了:

DbUtility Ex
  public static class MyExtensions
{
public static DataTable DT( this IDbExecutor<ParameterizedQuery> executor, string tableName )
{
ParameterizedQuery query = Db.T( "SELECT * FROM " + tableName );
return new DbExecutableQuery<ParameterizedQuery>( executor, query ).ExecuteDataTable();
}
}
DbUtility Ex

没错,借助优秀的可扩展架构,DbUtility可以被任意改造为任何你所喜欢 API 的形式,这种逆天的扩展性,是深深的植入在 DbUtility 整体架构模型设计中的。构成了 DbUtility 无与伦比的体验。

随笔分类 -C#

扩展 DbUtility (1)

2014-05-22 21:48 by Ivony..., 237 visits, 网摘收藏编辑

摘要: 不仅仅是开源,还手把手的教你怎么参与、扩展和修改DbUtility,借助强大的可扩展框架,DbUtility可以变成任何你想要的样子,这一篇文章介绍了如何扩展自己的查询构建方法。阅读全文

Jumony Core 3,真正的HTML引擎,正式版发布

2013-11-28 17:22 by Ivony..., 6556 visits, 网摘收藏编辑

摘要: Jumony是一个开源项目,已经有三年的历史了,在这三年中,秉承提供给.NET程序员完整的HTML掌控能力,Jumony历经无数次的改进,终于进入了一个新的阶段。Jumony Core 3是一个真正意义上的HTML引擎。Jumony Core 3目前已经在NuGet上发布,请直接在NuGet包管理器中搜索 Jumony Core ,即可下载。项目地址:https://github.com/Ivony/Jumony一、解析器也许很多人会认为,目前的HTML解析器已经足够了,甚至于简单的正则,也已经可以满足操纵HTML文档的需求。是的,对于互联网上绝大多数的HTML文档,事实上都大部分满足了XHT阅读全文

新项目,WebTest

2013-11-02 13:28 by Ivony..., 599 visits, 网摘收藏编辑

摘要: 最近为了给Jumony for ASP.NET进行单元测试有点伤神,ASP.NET因为环境特殊,一直是单元测试的禁地,传统的单元测试工具由于运行在非ASP.NET环境,可谓是举步维艰。当然,微软在搞ASP.NET MVC的时候已经注意到了这一点,雇了很多个临时工把HttpContext以及所有的相关类型全部写了个Base和Wrapper类型,用来Mock一个HttpContext假装在ASP.NE...阅读全文

Jumony Core 2.2 发布

2012-12-20 12:50 by Ivony..., 1926 visits, 网摘收藏编辑

摘要: Jumony Core 2.2 已经在 Nuget 上发布了。Jumony Core 是 Jumony 项目(http://jumony.codeplex.com)的一部分,提供基础的 HTML DOM 解析、API 和 CSS 选择器支持。对于 HTML 规范的支持接近完美(完爆HtmlAgilityPack),完全再现浏览器对 DOM 和 CSS 选择器的分析结果。可以在下面的地址查看 Jumony Core 2.2 的分析演示:http://dom.jumony.net/770D3173E589B82FAA6D9FCABA692A1AFBB2FE12?selector=.post_ite阅读全文

C#5纯属YY的展望

2011-05-23 23:27 by Ivony..., 2894 visits, 网摘收藏编辑

摘要: 每次.NET出现新版本后,都会有大量对下个版本不靠谱的各种YY。尤其是C#,一些YY会从3开始,直到5。在这里我也不妨YY一下,谈谈我期盼了很久的一些语言特性,我尽可能会让这些YY靠谱一点,各位看官姑妄听之,姑妄看之。 1、namespace语句: namespace Ivony;令整个文件所有根定义,均在Ivony命名空间。虽然很无聊,但是的确可以减少花括号的层次。2、lambda语句块:Ex...阅读全文

Jumony入门(四)无缝体验

2010-12-24 00:39 by Ivony..., 3340 visits, 网摘收藏编辑

摘要: 在这一篇里面,我会来谈谈Jumony与现有技术的结合,以及带来的无缝的体验。在前面的文章中,我们见识了Jumony种种神奇的功能,它可以拦截一个HTML文件的请求,解析文件成为DOM,用选择器找出我们感兴趣的地方,并用简单的方法来绑定数据。这些看起来很酷,但做网站需要的不是一个看起来很酷的技术,如何与现有的成果兼容,如何利用现有的经验和积累,也是非常重要的问题。阅读全文

Jumony入门(三)初探解析器

2010-12-22 01:28 by Ivony..., 4437 visits, 网摘收藏编辑

摘要: 这一次我要谈到Jumony的HTML解析器,我将直接从互联网上随便抓一个页面来分析其所有链接信息并呈现为表格。阅读全文

Jumony入门(二)初识选择器

2010-12-20 17:05 by Ivony..., 3683 visits, 网摘收藏编辑

摘要: Jumony能干什么,这一次我将从一个具体的问题提出Jumony的解决方案,展现Jumony神奇的魅力。阅读全文
分类: .NETC#