通用性站点管理后台(Bee OPOA Platform) (4)- DAL

该篇将介绍一下该平台中数据库访问层。设计之初考虑的主要偏向于方便应用, 由此数据访问层支持

1. 简单, 方便, 高效。 API简单高效。

2. 支持嵌套调用。 DbSession.Current

3. 通用。 支持主流数据库应用。 已使用验证过的包括Sqlite, SqlServer2008, SqlServer2005, Oracle。

DbSession的介绍

先来看一下DbSession的主要API。

   /* 实现IDisposable接口, 推荐使用using方式*/
    public sealed class DbSession : IDisposable
    {
        public DbSession(string connectionName) { /*使用配置文件中的连接名, 默认不启用事务*/ }
        public DbSession(string connectionName, bool useTransaction) {/*使用配置文件中的连接名, 是否启用事务*/  }

        /// <summary>
        /// 手动注册连接字符串。
        /// </summary>
        public static void Register(string connectionName,
            string providerName, string connectionString) { }

        public int CommandTimeout { get; set; }/* 该实例调用的超时时间*/

        public static DbSession Current
        {
            get; /* 获取当前上下文中DbSession实例, 不跨线程。 若上下文中未声明过, 则使用配置文件中第一个连接。*/
        }

        public void CommitTransaction()
        {
            /* 提交事务, 若不执行, 则自动rollback。 若中途抛异常, 自动rollback。*/
        }

        public int Insert(string tableName, BeeDataAdapter dataAdapter)
        {
            /* 指定表名, 插入数据集。 若不是该表中的字段, 则自动忽略。*/
        }

        public void Update(string tableName, BeeDataAdapter dataAdapter, SqlCriteria sqlCriteria)
        {
            /*指定表名, 数据集, 及条件集, 更新表*/
        }

        public void Delete(string tableName, SqlCriteria sqlCriteria)
        {
            /*指定表名, 及条件集, 删除数据*/
        }

        public DataTable Query(string tableName, SqlCriteria sqlCriteria) { }
        public DataTable Query(string tableName, SqlCriteria sqlCriteria, string orderbyClause) { }
        public DataTable Query(string tableName, string selectClause,
            SqlCriteria sqlCriteria, string orderbyClause, int pageIndex, int pageSize, ref int recordCount) { }

        public DataTable ExecuteCommand(string cmdText, BeeDataAdapter dataAdapter) { }
        public List<T> ExecuteCommand<T>(string cmdText, BeeDataAdapter dataAdapter){}

        public int Insert<T>(T value) { }
        public void Delete<T>(SqlCriteria sqlCriteria) { }
        public int Save<T>(T value) { }
        public List<T> Query<T>() { }
        public List<T> Query<T>(SqlCriteria sqlCriteria) { }
        public List<T> Query<T>(SqlCriteria sqlCriteria, string orderbyClause,
            int pageIndex, int pageSize, ref int recordCount) { }

        public DataTable CallSP(string spName, BeeDataAdapter dataAdapter)
        {
            /*调用存储过程。 若数据中的参数不是该存储过程的参数, 则自动忽略。 请注意存储过程的参数列表被缓存。 */
        }

        #region Schema Access

        /// <summary>
        /// 获取所有Table, SP, View
        /// </summary>
        public List<DbObject> GetDbObject() { }

        public TableSchema GetTableSchema(string tableName) { }
        public SPSchema GetSpSchema(string spName) { }

        /// <summary>
        /// 根据表结构, 获取创建表sql
        /// </summary>
        public string ToCreateTableScript(TableSchema tableSchema) { }

        /// <summary>
        /// 通过类型获取表结构
        /// </summary>
        public TableSchema GetEntitySchema(Type type) { }

        #endregion
    }

接口定义中, 大部分日常操作都能满足。 该接口同时可以满足获取DataTable及Orm方式。

DbSesion的嵌套调用

嵌套应用还是比较常用的, 尤其是在分层系统应用中。 很多底层方法都是完成特定功能的, 如获取单据号。 如下方法:

        public string GetBillId(string billType)
        {
            string result = string.Empty;

            BillTypeConfig billTypeConfig = null;

            DbSession dbSession = DbSession.Current;

            DateTime dateTime = DateTime.Today;

            string billDate = ""; // 当期, 如20121225, 201212.
            billTypeConfig = dbSession.Query<BillTypeConfig>(
                SqlCriteria.New.Equal("billtype", billType).Equal("billdate", billDate)).FirstOrDefault();

            if (billTypeConfig == null)
            {
                billTypeConfig = new BillTypeConfig();
                billTypeConfig.BillType = billType;
                billTypeConfig.BillDate = billDate;
                billTypeConfig.LastId = 1;
            }
            else
            {
                billTypeConfig.LastId = billTypeConfig.LastId + 1;
            }

            dbSession.Save(billTypeConfig);

            // 拼凑单据号

            return result;
        }

如没有上述代码中红色标注这一句, 一般实现要不就不管事务, 要不就需要将当前的访问数据库的上下文作为变量传进来。 若用DbSession.Current处理该类情况, 则十分的优雅, 该方法会自动根据调用方的连接走, 无论是换个连接, 还是是否启用事务。

简单ORM实现

所有的泛型QueryAPI其实都是先获取了DataTable后, 再进行ORM映射的。 之间的转换也是通过Emit动态生成接口(一个接口的实现)实现的。

posted @ 2012-12-25 15:19    阅读(3416)  评论(2编辑  收藏  举报