Wind-Eagle

No pain,no gain!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

数据访问层组件设计以及选型意识流 第一次封装

Posted on 2012-08-06 12:53  Andrew Yin  阅读(284)  评论(0编辑  收藏  举报

接上篇。。。

 

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

 

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操作。

 

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