惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AI
AI
WordPress大学
WordPress大学
博客园 - 聂微东
Hugging Face - Blog
Hugging Face - Blog
小众软件
小众软件
V
V2EX
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google DeepMind News
Google DeepMind News
V
Visual Studio Blog
The GitHub Blog
The GitHub Blog
IT之家
IT之家
D
Docker
M
MIT News - Artificial intelligence
D
DataBreaches.Net
博客园 - 三生石上(FineUI控件)
酷 壳 – CoolShell
酷 壳 – CoolShell
量子位
博客园_首页
Y
Y Combinator Blog
F
Full Disclosure
Microsoft Security Blog
Microsoft Security Blog
月光博客
月光博客
C
CXSECURITY Database RSS Feed - CXSecurity.com
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Spread Privacy
Spread Privacy
Know Your Adversary
Know Your Adversary
A
Arctic Wolf
Vercel News
Vercel News
T
Threat Research - Cisco Blogs
T
Threatpost
Apple Machine Learning Research
Apple Machine Learning Research
L
LINUX DO - 热门话题
T
The Exploit Database - CXSecurity.com
N
Netflix TechBlog - Medium
GbyAI
GbyAI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
Tailwind CSS Blog
J
Java Code Geeks
爱范儿
爱范儿
Cisco Talos Blog
Cisco Talos Blog
博客园 - 叶小钗
Latest news
Latest news
C
Check Point Blog
阮一峰的网络日志
阮一峰的网络日志
博客园 - Franky
P
Privacy International News Feed
MyScale Blog
MyScale Blog
Project Zero
Project Zero
Simon Willison's Weblog
Simon Willison's Weblog

博客园 - Andrew Yin

数据访问层组件设计以及选型意识流 第四次扩展的讨论 数据访问层组件设计以及选型意识流 第三次封装(极致、极简而不简单) 数据访问层组件设计以及选型意识流 第二次封装以及各种牢骚 数据访问层组件设计以及选型意识流 开篇 UTF-8, Unicode, GB2312三种编码方式解析, 深入研究汉字编码 C++中的模板实例:链表模板 一步一步学Ruby系列(二):Ruby中的函数 一步一步学Ruby系列(一):Ruby基础知识 .NET下的AOP: PostSharp 原理分析 AST,DLR,Expression Tree-----------推荐一位牛人的博客! C# 交互式SHELL C#中的 eval System.Web.Routing命名空间代码解析(四) Route解析中用到的实体类,一些以"Segment”为名的类 System.Web.Routing命名空间代码解析(三) RouteCollection类 System.Web.Routing命名空间代码解析(二) Routing类(上) System.Web.Routing命名空间代码解析(一) RouteBase类,RouteData类,RouteValueDictionary类 ASP.NET MVC中的各种上下文对象 有关string和Cookie的几个有用的扩展方法 反射加异步,根据枚举值来异步执行方法 操作Enum的一些实用方法
数据访问层组件设计以及选型意识流 第一次封装
Andrew Yin · 2012-08-06 · via 博客园 - Andrew Yin

接上篇。。。

除了上篇说到的以外,我们还完全抄袭了微软企业库里的这三个文件:

DbConnectionStore.cs 读取连接字符串的配置
DAABSectionHandler.cs 读取Provider配置
Field.cs 方便读取 DataReader, 和获取输出参数值,返回参数值的类,其实一点都不方便(被后面的DbUtil类替代),我们没有怎么用到

 微软后来还创建了一个Param类,代码很简单:

    

public class Param : List<IDataParameter>
    {
        public Param(DbProvideType provider)
        {
            Ado = AdoHelper.CreateHelper(provider);
        }

        public Param()
        {
        }

        public AdoHelper Ado { getset; }
    }

还创建了一个DbUtil的类,可能是觉得Feild类实在是太老土了,现在不是都流行扩展方法么?不是流行在方法里返回this已实现连续操作吗?

因此,DbUtil里的获取参数值和IDataRecord的方法是这样的:

 

添加参数的方法是这样的:

 

当然DbUtil里还有这些代码:

        

public static AdoHelper DefaultADO = AdoHelper.CreateHelper(DbProvideType.SqlServer);

        public static List<IDataParameter> CreateOracleParam()
        {
            // NOTE: 不建议直接使用因为不是从缓存获取
            return new Param(DbProvideType.Oracle);
        }

        public static List<IDataParameter> CreateSqlServerParam()
        {
            // NOTE: 不建议直接使用因为不是从缓存获取
            return new Param(DbProvideType.SqlServer);
        }

        public static List<IDataParameter> CreateParam(this AdoHelper helper)
        {
            return new Param
                       {
                           Ado = helper
                       };
        }

 其实DbUtil中的很多方法也是基本用不到的,因为,我们最终的版本就要直接返回实体对象的,不存在直接读IDataRecord,我们也不推荐使用输出参数!但是,我们对DbUtil类先照抄不误吧。

现在,就让我们进行第一次封装吧。

我特别讨厌DataReader和DataSet,DataTable,DataRow,DataRecord等东西,我喜欢强类型的实体,因此,我要数据访问框架来帮我把DataReader转换成实体,这是我们第一次封装的目的。

DataSet要不要也转? NO,我完全弃用DataSet!

因此,我创建了一个静态类:Query4Entity

创建了四个静态泛型方法:

        

public static T QuerySpForEntity<T, TU, TE>(this AdoHelper helper, TU conn, string spName,
                                            TE param, Action<object> action, out List<IDataParameter> parameters, string conAlians = nullstring cmdAlians = null)
            where T : class
            where TU : class
            where TE : class
        {
        }

        public static T QuerySqlForEntity<T, TU, TE>(this AdoHelper helper, TU conn, string sqlText,
                                            TE param, Action<object> action, out List<IDataParameter> parameters, string conAlians = nullstring cmdAlians = null)
            where T : class
            where TU : class
            where TE : class
        {
        }

        public static List<T> QuerySpForList<T, TU, TE>(this AdoHelper helper, TU conn, string spName,
                                            TE param, Action<object> action, out List<IDataParameter> parameters, string conAlians = nullstring cmdAlians = null)
            where T : class
            where TU : class
            where TE : class
        {
        }

        public static List<T> QuerySqlForList<T, TU, TE>(this AdoHelper helper, TU conn, string sqlText,
                                            TE param, Action<object> action, out List<IDataParameter> parameters, string conAlians = nullstring cmdAlians = null)
            where T : class
            where TU : class
            where TE : class
        {
        }

 T类型是返回实体的类型,TU和TE是第一篇中提到的 数据库连接参数的类型 和 SQL命令参数的类型。

我们只是做了一件简单的事,就是把返回的DataReader根据OR Mapping的配置转换为实体。

现在在来看看,我们的OR Mapping的配置文件吧。

 

 请特别注意parameters 配置节和 returnobjects配置节。

 到目前为止,我们的思路很清晰,做的事情也非常简单。应该说目前已经是可用的基础组件了,可能比DAAB更好用吧!

但是,我们的用户是挑剔的,有的用户提出了三个要求:

1. 加入分布式事务的支持

2. 我不想写任何SQL,我就是想做一些简单的单表数据库操作,能不能自动生成SQL语句?

3. 我想要像EF或者NH那样的父对象的SAVE调用会把子对象都SAVE的功能,我称为级联SQL操作。

好,我们接下来还有两次封装,来实现用户的这些需求!