ASP.NET 一個數據訪問層的封裝


剛通過開通寫博客的申請,向博客園的大佬致敬,由於一直以來都在網上搜索大家的思想,也有翻遍整個百度都有的找不到的時候,作為一個網民理應為互聯網貢獻一點東西。

下面是我工作后受一個師傅的影響對數據庫訪問層的封裝,多年以來一直都在使用,用的特別爽,請看下面的代碼:

第一步、需要編寫一個通用的用於查詢的數據庫存儲過程,這個存儲過程接受“表名、查詢字段、排序、頁大小、頁碼”:

CREATE PROCEDURE [dbo].[P_Pagination] 
    @tblName varchar(5000), -- 表名
    @strGetFields varchar(1000) = '*', -- 需要返回的列
    @strWhere varchar(1500) = '', -- 查詢條件(注意: 不要加 where)
    @OrderSql varchar(255) = '', -- 排序語句(注意: 不要加 order by)
    @PageSize int = 0, -- 頁尺寸
    @PageIndex int = 1, -- 頁碼
    @doCount bit = 0 -- 返回記錄總數,非 0 值則返回
AS
BEGIN
    declare @strSQL varchar(5000) -- 主語句

    if @doCount <> 0
    begin
        if @strWhere <> ''
            set @strSQL = 'select count(*) as Total from ' + @tblName + ' where ' + @strWhere
        else
            set @strSQL = 'select count(*) as Total from ' + @tblName + ''
    end
    --以上代碼的意思是如果@doCount傳遞過來的不是0,就執行總數統計。以下的所有代碼都是@doCount為0的情況
    else
    begin
        if @PageSize = 0 --返回所有記錄集
        begin
            if @strWhere <> ''
                set @strSQL = 'select ' + @strGetFields + ' from ' + @tblName + ' where ' + @strWhere + ' order by ' + @OrderSql
            else
                set @strSQL = 'select ' + @strGetFields + ' from ' + @tblName + ' order by ' + @OrderSql
        end
        else 
        begin
            if @PageIndex = 1
            begin
                if @strWhere <> ''
                    set @strSQL = 'select top ' + str(@PageSize) + ' ' + @strGetFields + ' from ' + @tblName + ' where ' + @strWhere + ' order by ' + @OrderSql
                else
                    set @strSQL = 'select top ' + str(@PageSize) + ' ' + @strGetFields + ' from ' + @tblName + ' order by ' + @OrderSql
                --如果是第一頁就執行以上代碼,這樣會加快執行速度
            end
            else
            begin
                --以下代碼賦予了@strSQL以真正執行的SQL代碼
                if @strWhere = ''
                    set @strSQL = 'select top ' + str(@PageSize) + ' tblTmp.* from '
                        + '(select ROW_NUMBER() OVER(order by ' + @OrderSql + ') AS RowNum,' + @strGetFields + ' from ' + @tblName + ') tblTmp where tblTmp.[RowNum] > '
                            + '(select max([RowNum]) from '
                                + '(select top ' + str((@PageIndex - 1) * @PageSize) + ' ROW_NUMBER() OVER(order by ' + @OrderSql + ') AS RowNum from ' + @tblName + ') as tblTmp1)'
                else
                    set @strSQL = 'select top ' + str(@PageSize) + ' tblTmp.* from '
                        + '(select ROW_NUMBER() OVER(order by ' + @OrderSql + ') AS RowNum,' + @strGetFields + ' from ' + @tblName + ' where ' + @strWhere + ') tblTmp where tblTmp.[RowNum] > '
                            + '(select max([RowNum]) from '
                                + '(select top ' + str((@PageIndex - 1) * @PageSize) + ' ROW_NUMBER() OVER(order by ' + @OrderSql + ') AS RowNum from ' + @tblName + ' where ' + @strWhere + ') as tblTmp1)'
            end
        end
    end
    exec (@strSQL);
END

第二步、封裝數據庫訪問層,該層實現執行存儲過程或SQL語句返回 DataTable、SqlDataReader、受影響行數:

namespace Ant.DAL
{
    /// <summary>
    /// 存儲過程返回值
    /// </summary>
    public class ProcResultValue
    {
        /// <summary>
        /// @Result 字符串返回值
        /// </summary>
        public string ResultValueStr { get; set; }

        /// <summary>
        /// Return 任意類型返回值
        /// </summary>
        public int ReturnValueInt { get; set; }

        /// <summary>
        /// 存儲過程異常實體信息返回
        /// </summary>
        public string ReturnValue
        {
            get
            {
                if (ReturnValueInt <= 0)
                    return ResultValueStr;
                else
                    return "";
            }
        }
    }

    /// <summary>
    /// 數據庫基礎操作類
    /// </summary>
    public class Database
    {
        // 測試用Sql連接字符串
        private static string SqlConn_Debug = System.Configuration.ConfigurationManager.ConnectionStrings["ConnDB"].ToString();/// <summary>
        /// 數據庫基礎操作類 構造函數
        /// </summary>
        public Database()
        {
        }

        /// <summary>
        /// 獲得數據庫連接數據
        /// </summary>
        /// <returns>數據庫連接信息</returns>
        protected SqlConnection GetConn()
        {
            SqlConnection ConnDB = new SqlConnection(SqlConn_Debug);
            ConnDB.StateChange += new StateChangeEventHandler(ConnDB_StateChange);
            ConnDB.Open();
            return ConnDB;
        }

        /// <summary>
        /// 數據庫鏈接狀態改變事件
        /// </summary>
        protected void ConnDB_StateChange(object sender, StateChangeEventArgs e)
        {
            if (e.CurrentState == ConnectionState.Closed)
            {
                ((SqlConnection)sender).Dispose(); // 釋放資源
                GC.Collect(); // 釋放資源
            }
        }

        /// <summary>
        /// 獲得對應表序列的新ID
        /// </summary>
        /// <param name="TableName">表名</param>
        /// <param name="TableCol">表ID列名</param>
        /// <param name="TableWhere">查詢條件(注意:不添加'where')</param>
        /// <returns>返回:序列的新ID</returns>
        protected int GetSequence(string TableName, string TableCol, string tableWhere = "")
        {
            DataParameters DP = new DataParameters();
            DP.Add("@TableName", SqlDbType.VarChar, TableName);
            DP.Add("@TableCol", SqlDbType.VarChar, TableCol);
            DP.Add("@tableWhere", SqlDbType.VarChar, tableWhere);
            return ExeProc("P_Sequence", DP, false).ReturnValueInt;
        }

        /// <summary>
        /// 通過存儲過程,獲得數據集 DataReader
        /// </summary>
        /// <param name="tblName">要查詢的表名</param>
        /// <param name="strGetFields">要查詢的字段</param>
        /// <param name="strWhere">查詢條件(注意:不要加 "where")</param>
        /// <param name="OrderSql">排序規則(注意:不要加 "order by",且不能為空)</param>
        /// <param name="PageSize">頁大小 為0時,則不分頁</param>
        /// <param name="PageIndex">頁索引</param>
        /// <returns>返回:記錄集 SqlDataReader</returns>
        protected SqlDataReader GetDataReader(string tblName, string strGetFields, string strWhere, string OrderSql, int PageSize, int PageIndex)
        {
            SqlCommand Cmd = new SqlCommand("P_Pagination", GetConn());
            Cmd.CommandType = CommandType.StoredProcedure;
            Cmd.Parameters.Add("@tblName", SqlDbType.VarChar).Value = tblName;
            Cmd.Parameters.Add("@strGetFields", SqlDbType.VarChar).Value = strGetFields;
            Cmd.Parameters.Add("@strWhere", SqlDbType.VarChar).Value = strWhere;
            Cmd.Parameters.Add("@OrderSql", SqlDbType.VarChar).Value = OrderSql;
            Cmd.Parameters.Add("@PageSize", SqlDbType.Int).Value = PageSize;
            Cmd.Parameters.Add("@PageIndex", SqlDbType.Int).Value = PageIndex;
            Cmd.Parameters.Add("@doCount", SqlDbType.Bit).Value = false;
            return Cmd.ExecuteReader(CommandBehavior.CloseConnection);
        }

        /// <summary>
        /// 通過存儲過程及自定義參數,獲得數據集 DataReader
        /// </summary>
        /// <param name="ProcName">存儲過程名</param>
        /// <param name="DataParas">存儲過程參數集</param>
        /// <returns>返回:記錄集 SqlDataReader</returns>
        protected SqlDataReader GetDataReader(string ProcName, DataParameters DataParas)
        {
            SqlCommand Cmd = new SqlCommand(ProcName, GetConn());
            Cmd.CommandType = CommandType.StoredProcedure;

            // 遍歷 存儲過程參數集
            foreach (System.Collections.DictionaryEntry obj in DataParas.Parameters)
            {
                Cmd.Parameters.Add(obj.Key.ToString(), (SqlDbType)((object[])obj.Value)[0]).Value = ((object[])obj.Value)[1];
            }
            return Cmd.ExecuteReader(CommandBehavior.CloseConnection);
        }

        /// <summary>
        /// 通過存儲過程,獲得數據集 DataTable
        /// </summary>
        /// <param name="tblName">要查詢的表名</param>
        /// <param name="strGetFields">要查詢的字段</param>
        /// <param name="strWhere">查詢條件(注意:不要加 "where")</param>
        /// <param name="OrderSql">排序規則(注意:不要加 "order by",且不能為空)</param>
        /// <param name="PageSize">頁大小 為0時,則不分頁</param>
        /// <param name="PageIndex">頁索引</param>
        /// <returns>返回:記錄集 DataTable</returns>
        protected DataTable GetDataTable(string tblName, string strGetFields, string strWhere, string OrderSql, int PageSize, int PageIndex)
        {
            SqlCommand Cmd = new SqlCommand("P_Pagination", GetConn());
            Cmd.CommandType = CommandType.StoredProcedure;
            Cmd.Parameters.Add("@tblName", SqlDbType.VarChar).Value = tblName;
            Cmd.Parameters.Add("@strGetFields", SqlDbType.VarChar).Value = strGetFields;
            Cmd.Parameters.Add("@strWhere", SqlDbType.VarChar).Value = strWhere;
            Cmd.Parameters.Add("@OrderSql", SqlDbType.VarChar).Value = OrderSql;
            Cmd.Parameters.Add("@PageSize", SqlDbType.Int).Value = PageSize;
            Cmd.Parameters.Add("@PageIndex", SqlDbType.Int).Value = PageIndex;
            Cmd.Parameters.Add("@doCount", SqlDbType.Bit).Value = false;
            SqlDataAdapter DA = new SqlDataAdapter(Cmd);
            DataTable DT = new DataTable();
            DA.Fill(DT);
            Cmd.Connection.Close();
            return DT;
        }

        /// <summary>
        /// 通過指定的存儲過程名稱,獲取數據集 DataTable
        /// </summary>
        /// <param name="ProcName">存儲過程名</param>
        /// <param name="DataParas">存儲過程參數集</param>
        /// <returns>返回:記錄集 DataTable</returns>
        protected DataTable GetDataTable(string ProcName, DataParameters DataParas = null)
        {
            SqlCommand Cmd = new SqlCommand(ProcName, GetConn());
            Cmd.CommandType = CommandType.StoredProcedure;

            // 遍歷 存儲過程參數集
            if(DataParas != null)
            {
                foreach (System.Collections.DictionaryEntry obj in DataParas.Parameters)
                {
                    Cmd.Parameters.Add(obj.Key.ToString(), (SqlDbType)((object[])obj.Value)[0]).Value = ((object[])obj.Value)[1];
                }
            }
            SqlDataAdapter DA = new SqlDataAdapter(Cmd);
            DataTable DT = new DataTable();
            DA.Fill(DT);
            Cmd.Connection.Close();
            return DT;
        }

        /// <summary>
        /// 執行SQL查詢語句,獲取數據集 DataReader
        /// </summary>
        /// <param name="sqlTxt">要執行的SQL語句</param>
        /// <returns>返回:記錄集 DataReader</returns>
        protected SqlDataReader GetDataReader(string sqlTxt)
        {
            SqlCommand Cmd = new SqlCommand(sqlTxt, GetConn());
            Cmd.CommandType = CommandType.Text;
            return Cmd.ExecuteReader(CommandBehavior.CloseConnection);
        }

        /// <summary>
        /// 執行SQL查詢語句,獲取數據集 DataTable
        /// </summary>
        /// <param name="sqlTxt">要執行的SQL語句</param>
        /// <returns>返回:記錄集 DataTable</returns>
        protected DataTable GetDataTable(string sqlTxt)
        {
            SqlCommand Cmd = new SqlCommand(sqlTxt, GetConn());
            Cmd.CommandType = CommandType.Text;
            SqlDataAdapter DA = new SqlDataAdapter(Cmd);
            DataTable DT = new DataTable();
            DA.Fill(DT);
            Cmd.Connection.Close();
            return DT;
        }

        /// <summary>
        /// 通過存儲過程,獲得數據集 總數
        /// </summary>
        /// <param name="tblName">要查詢的表名</param>
        /// <param name="strWhere">查詢條件</param>
        /// <returns>返回:記錄集數量</returns>
        protected int GetDataCount(string tblName, string strWhere = "")
        {
            SqlCommand Cmd = new SqlCommand("P_Pagination", GetConn());
            Cmd.CommandType = CommandType.StoredProcedure;
            Cmd.Parameters.Add("@tblName", SqlDbType.VarChar).Value = tblName;
            Cmd.Parameters.Add("@strGetFields", SqlDbType.VarChar).Value = "*";
            Cmd.Parameters.Add("@strWhere", SqlDbType.VarChar).Value = strWhere;
            Cmd.Parameters.Add("@OrderSql", SqlDbType.VarChar).Value = "";
            Cmd.Parameters.Add("@PageSize", SqlDbType.Int).Value = 0;
            Cmd.Parameters.Add("@PageIndex", SqlDbType.Int).Value = 1;
            Cmd.Parameters.Add("@doCount", SqlDbType.Bit).Value = true;
            int Result = (int)Cmd.ExecuteScalar();
            Cmd.Connection.Close();
            return Result;
        }

        /// <summary>
        /// 執行SQL查詢語句,並返回數據集長度
        /// </summary>
        /// <param name="sqlTxt">要執行的SQL語句</param>
        /// <returns>返回:數據集長度</returns>
        protected int GetDataCount(string sqlTxt)
        {
            SqlCommand Cmd = new SqlCommand(sqlTxt, GetConn());
            Cmd.CommandType = CommandType.Text;
            SqlDataAdapter DA = new SqlDataAdapter(Cmd);
            DataTable DT = new DataTable();
            DA.Fill(DT);
            Cmd.Connection.Close();
            return DT.Rows.Count;
        }

        /// <summary>
        /// 執行查詢語句,並返回第一行第一列數據
        /// </summary>
        /// <param name="SelectTxt">要執行的查詢語句</param>
        /// <returns>返回查詢結果集的第一行第一列數據</returns>
        protected object GetOnlyData(string SelectTxt)
        {
            SqlCommand Cmd = new SqlCommand(SelectTxt, GetConn());
            object Result = Cmd.ExecuteScalar();
            Cmd.Connection.Close();
            return Result;
        }

        /// <summary>
        /// 執行語句,並返回受影響的行數
        /// </summary>
        /// <param name="CmdTxt">要執行的 增、刪、改 語句</param>
        /// <returns>返回受影響的行數</returns>
        protected int RunSqlCommand(string CmdTxt)
        {
            SqlCommand Cmd = new SqlCommand(CmdTxt, GetConn());
            int ExecuteCount = Cmd.ExecuteNonQuery();
            Cmd.Connection.Close();
            Cmd.Dispose();
            return ExecuteCount;
        }

        /// <summary>
        /// 執行存儲過程,並返回存儲過程執行結果(字符串)
        /// </summary>
        /// <param name="ProcName">存儲過程名稱</param>
        /// <param name="DataParas">存儲過程參數集</param>
        /// <param name="HasResult">該存儲過程是否有返回值</param>
        /// <returns>存儲過程返回值</returns>
        protected ProcResultValue ExeProc(string ProcName, DataParameters DataParas, bool HasResult)
        {
            // 此處預留異常處理Try catch, 由Application獲取並跳轉異常頁面。
            // 返回值
            ProcResultValue Result = new ProcResultValue();

            // 創建 Command
            SqlCommand Cmd = new SqlCommand(ProcName, GetConn());
            Cmd.CommandType = CommandType.StoredProcedure;
            
            // 遍歷 存儲過程參數集
            foreach (System.Collections.DictionaryEntry obj in DataParas.Parameters)
            {
                Cmd.Parameters.Add(obj.Key.ToString(), (SqlDbType)((object[])obj.Value)[0]).Value = ((object[])obj.Value)[1];
            }

            // 創建返回參數
            if (HasResult)
            {
                Cmd.Parameters.Add("@Result", SqlDbType.NVarChar, -1);
                Cmd.Parameters["@Result"].Direction = ParameterDirection.Output;
            }

            //存儲過程默認返回值  存儲過程:Return
            Cmd.Parameters.Add("@Return", SqlDbType.Int);
            Cmd.Parameters["@Return"].Direction = ParameterDirection.ReturnValue;

            // 執行存儲過程
            Cmd.ExecuteNonQuery();

            // 獲得返回值
            if (HasResult)
                Result.ResultValueStr = Cmd.Parameters["@Result"].Value.ToString();
            Result.ReturnValueInt = (Cmd.Parameters["@Return"].Value is int ? (int)Cmd.Parameters["@Return"].Value : -1);

            // 關閉數據庫鏈接
            Cmd.Connection.Close();

            // 在這里執行一些存儲過程catch異常的操作
            if(Result.ReturnValueInt == -1)
            {

            }

            // 返回執行結果
            return Result;
        }

        /// <summary>
        /// 執行函數,並返回函數執行結果
        /// </summary>
        /// <param name="FuncName">函數名稱</param>
        /// <param name="DataParas">函數參數集</param>
        /// <param name="ResultType">返回值類型</param>
        /// <returns>存儲過程返回值</returns>
        protected object ExeFunc(string FuncName, DataParameters DataParas, SqlDbType ResultType)
        {
            // 返回值
            object Result = null;

            // 創建 Command
            SqlCommand Cmd = new SqlCommand(FuncName, GetConn());
            Cmd.CommandType = CommandType.StoredProcedure;

            // 遍歷 存儲過程參數集
            foreach (System.Collections.DictionaryEntry obj in DataParas.Parameters)
            {
                Cmd.Parameters.Add(obj.Key.ToString(), (SqlDbType)((object[])obj.Value)[0]).Value = ((object[])obj.Value)[1];
            }

            // 創建返回參數
            Cmd.Parameters.Add("@Return", ResultType, -1);
            Cmd.Parameters["@Return"].Direction = ParameterDirection.ReturnValue;

            // 執行存儲過程
            Cmd.ExecuteScalar();

            // 獲得返回值
            Result = Cmd.Parameters["@Return"].Value;

            // 關閉數據庫鏈接
            Cmd.Connection.Close();

            // 返回執行結果
            return Result;
        }
    }
}

第三步、上面對數據庫訪問封裝方法有一個DataParameters傳參對象,你沒有想錯,這個對象是自己封裝的類,調用起來更加方便,請看下面代碼

namespace Ant.DAL
{
    /// <summary>
    /// 數據庫[存儲過程、函數]參數類
    /// </summary>
    public class DataParameters
    {
        private Hashtable HT = new Hashtable(); // 存儲過程參數表

        /// <summary>
        /// 數據庫[存儲過程、函數]參數類 構造函數
        /// </summary>
        public DataParameters()
        {
        }

        /// <summary>
        /// 數據庫[存儲過程、函數] 參數表
        /// </summary>
        public Hashtable Parameters
        {
            get
            {
                return HT;
            }
        }

        /// <summary>
        /// 添加數據庫[存儲過程、函數]的參數
        /// </summary>
        /// <param name="ParaName">參數名稱</param>
        /// <param name="ParaType">參數類型</param>
        /// <param name="ParaValue">參數值</param>
        public void Add(string ParaName, SqlDbType ParaType, object ParaValue)
        {
            HT.Add(ParaName, new object[] { ParaType, ParaValue });
        }
    }
}

第四步、調用

        /// <summary>
        /// (查詢調用)根據條件查詢系統操作對象數據
        /// </summary>
        /// <param name="sqlField">查詢字段</param>
        /// <param name="sqlWhere">查詢條件 注:不要加 Where</param>
        /// <param name="orderBy">排序 注:不要加 Order By</param>
        /// <param name="pageSize">頁大小 大於等於 0</param>
        /// <param name="pageIndex">頁碼 大於等於 1</param>
        /// <returns>返回:SqlDataReader</returns>
        public SqlDataReader GetData(string sqlField, string sqlWhere, string orderBy, int pageSize, int pageIndex)
        {
            return base.GetDataReader("Base_Action", sqlField, sqlWhere, orderBy, pageSize, pageIndex);
        }

        /// <summary>
        /// (存儲過程增刪改調用)設置單條系統操作對象
        /// </summary>
        /// <param name="editSign">操作標識</param>
        /// <param name="ID">主鍵ID</param>
        /// <param name="Menu">類型ID(系統菜單ID、公共頁面對象ID)</param>
        /// <param name="Name">名稱:按鈕/鏈接ID</param>
        /// <param name="Text">描述:按鈕/連接名稱</param>
        /// <returns>返回:操作結果 空/異常信息</returns>
        public ProcResultValue SetActionInfo(SetActionInfo_EditSign editSign, long ID, long Menu, string Name, string Text)
        {
            DataParameters DP = new DataParameters();
            DP.Add("@EditSign", System.Data.SqlDbType.Int, (int)editSign);
            DP.Add("@ID", System.Data.SqlDbType.BigInt, ID);
            DP.Add("@Menu", System.Data.SqlDbType.BigInt, Menu);
            DP.Add("@Name", System.Data.SqlDbType.VarChar, Name);
            DP.Add("@Text", System.Data.SqlDbType.NVarChar, Text);
            return base.ExeProc("P_Base_Action", DP, true);
        }        

 


免責聲明!

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



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