通用性站點管理后台(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動態生成接口(一個接口的實現)實現的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM