微软企业库6DataAccessApplicationBlock扩展(一)

2015-07-24 08:59:03 · 作者: · 浏览: 0

虽然标题是对6的扩展,其实对于4、5同样适用,因为企业库在这几个版本中没太大变化

该扩展主要针对DataAccessor,该类在创建时要传递几种接口:IParameterMapper,IRowMapper,IResultSetMapper,其中IRowMapper企业库提供了MapBuilder静态类来辅助创建相应的对应关系,但对于IParameterMapper和IResultSetMapper没提供现成的类(也许有,但我没找到,毕竟没去研究它的源码

以下是具体相关的代码,设计思路是:IParameterMapper和IResultSetMapper其实都是要实现一个约定的方法,而对于该方法,我直接设置通用类,该类接受具体的实现委托,该委托由coder决定,而无需coder反复去创建相关类,减少代码量

PS:DbCommand.Parameters.AddRange接受DbParameter参数,所以可以直接传递具体的DbParameter

1、GeneralParameterMapper

    /// 
    /// 通用IParameterMapper
    /// 如果在Execute前要传递的DbParameter已被其它DbCommand使用,将产生异常
    /// 所以应该要调用DbCommand.Parameters.Clear方法释放其它DbCommand对DbParameter的占用
    /// 
    public class GeneralParameterMapper : IParameterMapper
    {
        private Action _act;
        /// 
        /// GeneralParameterMapper
        /// 
        /// 
        /// 定义如何将parameterValues赋给DbCommand的委托
        /// 如果不传,将使用默认委托,该委托不校验要传递的parameterValues在DbCommand是否已定义
        /// 此时反复执行Execute将会导致异常,以保证不会因为编码问题导致反复查询
        public GeneralParameterMapper(Action act = null)
        {
            if (act != null)
            {
                this._act = act;
            }
            else
            {
                this._act = (cmd, paramters) =>
                {
                    cmd.Parameters.AddRange(paramters);
                };
            }
        }
        #region IParameterMapper 成员
        /// 
        /// IParameterMapper.AssignParameters
        /// 
        /// 
        /// 
        public void AssignParameters(DbCommand command, object[] parameterValues)
        {
            if (parameterValues != null && parameterValues.Length > 0)
            {
                this._act(command, parameterValues);
            }
        }

        #endregion
    }
2、GeneralResultSetMapper

    /// 
    /// 通用IResultSetMapper
    /// 
    /// 
    public class GeneralResultSetMapper : IResultSetMapper
    {
        private Func _func;
        /// 
        /// GeneralResultSetMapper
        /// 
        /// 根据IDataReader如何返回T委托
        public GeneralResultSetMapper(Func func)
        {
            if (func == null)
            {
                throw new ArgumentNullException();
            }
            this._func = func;
        }
        #region IResultSetMapper 成员
        /// 
        /// IResultSetMapper.MapSet
        /// 
        /// IDataReader
        /// List集合,如果Count为0,表示无数据,不会返回null值
        public IEnumerable MapSet(IDataReader reader)
        {
            List list = new List();
            while (reader.Read())
            {
                list.Add(this._func(reader));
            }
            return list;
        }

        #endregion
    }

在这两个类的基础上,又封装了个扩展类,专门用于微软企业库DataAccessor的扩展,以下是具体代码,因个人喜好问题,没封装对应Proc的扩展方法,其实代码都一样

    /// 
    /// 微软企业库数据相关的帮助类
    /// 
    public static class EntLibDbHelper
    {
        /// 
        /// 批量查询Sql并自动填充实体,如果不需要传递DbParameter,建议不要使用该方法,应使用Database.ExecuteSqlStringAccessor方法
        /// 
        /// 
        /// 
        /// 
        /// 指定委托确认对要传递的Sql参数如何处理,该值可以传递null,为null时使用默认委托,该委托直接将parameterValues传递给cmd.Parameters.AddRange方法
        /// 指示EntLib如何填充T,如果不传,将默认按T的属性进行对应赋值
        /// 要传递的Sql参数,此部分对应parameterMapperAction
        /// 
        public static IList ExecuteBySqlString(this Database db, string sql, Action parameterMapperAction, IRowMapper rowMapper = null, params object[] parameterValues)
            where T : new()
        {
            if (rowMapper == null)
            {
                rowMapper = MapBuilder.BuildAllProperties();
            }
            IParameterMapper parameterMapper = new GeneralParameterMapper(parameterMapperAction);
            return db.CreateSqlStringAccessor(sql, parameterMapper, rowMapper).Execute(parameterValues).ToList();
        }
        /// 
        /// 批量查询Sql并自动填充实体,如果不需要传递DbParameter,建议不要使用该方法,应使用Database.ExecuteSqlStringAccessor方法
        /// 
        /// 
        /// 
        /// 
        /// 指定委托确认对要传递的Sql参数如何处理,该值可以传递null,为null时使用默认委托,该委托直接将parameterValues传递给cmd.Parameters.AddRange方法
        /// 指示EntLib如何填充T
        /// 要传递的Sql参数,此部分对应parameterMapperAction
        /// 
        public static IList ExecuteBySqlString(this Database db, string sql, Action