前言
源代碼和調用演示下載:http://www.cnblogs.com/jyk/archive/2008/04/25/1170979.html
數據訪問函數庫for ado.net 1.1 的說明:http://www.cnblogs.com/jyk/category/67121.html
由於一直在使用vs2003開發,所以自己使用的數據訪問函數庫(以下簡稱:訪問庫)也就一直沒有能夠考慮到ado.net2.0。雖然ado.net2.0在調用的時候沒有什麼變化,但是內部結構卻發生了不小的變化,加了一系列的基類,使得更換數據庫更容易。
雖然把把現在的數據訪問函數庫使用vs2008打開,進行升級,然後就可以使用了,但是這樣的話就不能應用ado.net2.0的新的特性,而且原來不方便的地方也不能得到修正,所以打算這一回升級的徹底一點。
先貼一個屠大家看看
一、新的數據訪問函數庫的優點:
1、支持多種數據庫。
2、支持SQL語句、存儲過程、存儲過程的參數,對這些作了一些處理(封裝),使得調用的時候可以更方便。
3、支持ado.net的事務。
4、如果在運行的時候出現異常,可以把異常信息、函數名稱和SQL語句寫入“錯誤日志”裡面,這樣很方便程序員查找錯誤,上線使用後,也可以做一個記錄。
5、默認的數據庫類型和連接字符串在webconfig裡面設置。
<appSettings> <add key="DataType" value ="1"/> </appSettings> <connectionStrings> <add name="ConnStr" connectionString="Data Source=.;Initial Catalog=Northwind;Integrated Security=True" providerName="System.Data.SqlClient"/> </connectionStrings>
最主要的目的就是想要在調用的時候盡可能的方便!
二、新的知識點
升級的時候使用了一些以前不會的東東,比如 Dictionary字典、靜態初始化 等,當然第一次使用,可能用法不一定正確。還有就是用了幾個vs2008裡的新特性。
三、重復制造輪子
我知道企業庫都到了4.0了,但是我還是喜歡使用自己訪問庫。一是可以向下兼容,方便以前的項目(vs2003)升級到vs2008;二是習慣了,從03年開始使用.net,就一直使用自己寫的訪問庫操作數據庫;再有就是想自己寫一個鍛煉鍛煉。
四、一個自己看著都別扭的地方
ado.net1.1 的訪問庫比較簡單,所有相關的代碼都寫在了一個類裡面,想用那個函數就調用哪個函數,但是這樣總感覺有點浪費,因為這個訪問庫是需要實例化的,即使只使用裡面的一個函數,也要把整個類都實例化出來一個,當然我不知道這個過程到底占用多少資源,至少感覺上是很浪費的。
由於自己對於靜態函數還沒有很了解,所以還不敢把訪問庫改成靜態的方式,所以還的試用實例化的方式。那麼能不能使用哪一個部分就實例化那一部分,其他的先暫時不實例化呢?
於是我就把這幾個部分分成了五個類,在“主類”裡面定義一個,然後在需要的時候再實例化。(還是看代碼吧:))
public partial class DataAccessHelp : DbBase
{//這個是主類,在裡面定義三個成員,這時並不實例化,DataAccessHelp 初始化的時候也不實例化。
/// 處理存儲過程參數的管理部分 public ManagerStore ParameterMgr; /// 處理事務的管理部分 public ManagerTran TranMgr; /// 填充結構數組的部分 public ManagerWebStruct WebStructMgr; //然後再需要的時候再實例化 /// 加載處理存儲過程參數的實例。用這個實例來添加存儲過程的參數 public void LoadParameter() { if (ParameterMgr == null) { ParameterMgr = new ManagerStore(); } else { //清除Command裡面的參數 ParameterMgr.ClearParameter(); } ParameterMgr.dal = this; //把主類的實例傳遞進去 } } public class ManagerStore { /// <summary> /// 數據訪問函數庫的實例,主要是想操作Command /// </summary> public DataAccessHelp dal; //接收 DataAccessHelp 的實例 /// 添加int型的參數。 /// <param name="ParameterName">參數名稱。比如 @UserName</param> /// <param name="ParameterValue">參數值</param> public virtual void addNewParameter(string ParameterName, Int32 ParameterValue) { DbParameter par = dal.CreateParameter(ParameterName); par.DbType = DbType.Int32; par.Value = ParameterValue; //添加存儲過程的參數 dal.myCommand.Parameters.Add(par); } }
我都感覺別扭的地方就是上面粗體的部分。有一種互相調用的感覺,但是編譯和測試都通過了。
五、疑問
public static Dictionary<string, DbParameter> BaseParameter = new Dictionary<string, DbParameter>(); BaseParameter.Add("1", new System.Data.SqlClient.SqlParameter()); public DbParameter CreateParameter(string myParameterName) { DbParameter par = BaseParameter[this.DataType]; //new System.Data.SqlClient.SqlParameter(); //為了能夠正確運行,暫時用這一行的代碼代替。 par.ParameterName = myParameterName; return par; }
這樣的用法是不是每次調用的時候,par都會得到一個新的實例呢?
實際測試中卻發現:第一次調用的時候,par可以得到一個實例,但是在第二次調用的時候,得到的卻是上一次的調用產生的實例。是因為使用了靜態變量的原因嗎?還是說本來就是這樣的?
那麼如果我每次調用都想得到一個新的實例的話,上面的代碼應該怎麼寫呢?
六、調用
我習慣直接在 .aspx.cs 文件裡面調用,但是並不是說只能在這裡調用,也是可以在業務層或者是數據層裡調用,因為都是在類裡面調用。:)
簡單寫幾個,其他的在 http://www.cnblogs.com/jyk/archive/2008/04/25/1170979.html 這裡下載吧。當然如果您感覺這個不值一提,那就不占用您的寶貴時間了。
演示用的數據庫:Northwind。
private void DALTest() { //測試默認數據庫的sql語句 DataAccessHelp dal = new DataAccessHelp(); string str1 = dal.RunSqlGetFirstColValue("select ProductName from Products where ProductID = 1"); Response.Write("RunSqlGetFirstColValue測試:" + str1); string[] str2 = dal.RunSqlStrings("select * from Products where ProductID = 2"); GV_strings.DataSource = str2; GV_strings.DataBind(); string[] str3 = dal.RunSqlStringsByRow("select ProductName from Products "); GV_Arr.DataSource = str3; GV_Arr.DataBind(); DataRow dr1 = dal.RunSqlDataRow("select * from Products where ProductID = 3"); GV_DataRow.DataSource = dr1.Table; GV_DataRow.DataBind(); DataTable dt1 = dal.RunSqlDataTable("select * from Products where ProductID = 4"); GV_DataTable.DataSource = dt1; GV_DataTable.DataBind(); dal.Dispose(); } private void StoreTest() {//存儲過程的參數的測試 DataAccessHelp dal = new DataAccessHelp(); dal.LoadParameter(); dal.ParameterMgr.ClearParameter(); //清除參數 dal.ParameterMgr.AddNewParameter("@ProductName","產品名稱的測試",40); dal.ParameterMgr.AddNewParameter("@SupplierID", 23); dal.ParameterMgr.AddNewParameter("@CategoryID", 1); dal.ParameterMgr.AddNewParameter("@QuantityPerUnit","5 ml",20); dal.ParameterMgr.AddNewParameter("@UnitPrice",decimal.Parse("2.34")); dal.ParameterMgr.AddNewParameter("@UnitsInStock", 2); dal.ParameterMgr.AddNewParameter("@UnitsOnOrder", 3); dal.ParameterMgr.AddNewParameter("@ReorderLevel", 4); dal.ParameterMgr.AddNewParameter("@Discontinued",true); dal.ParameterMgr.RunStore("Proc_AddProduct"); DataRow dr1 = dal.RunSqlDataRow("select top 1 * from Products order by ProductID desc"); GV_DataRow.DataSource = dr1.Table; GV_DataRow.DataBind(); dal.Dispose(); } private void StoreShowDataTest() { DataAccessHelp dal = new DataAccessHelp(); dal.LoadParameter(); dal.ParameterMgr.AddNewParameter("@OrderID", 10250); this.GV_DataTable.DataSource = dal.ParameterMgr.RunStoreDataTable("CustOrdersDetail"); this.GV_DataTable.DataBind(); dal.Dispose(); } private void OleDbTest() {//非默認數據庫的調用方法,以access數據庫為例 string cnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=E:\\VS2008\\a.mdb;"; DataAccessHelp dal = new DataAccessHelp("2", cnString); this.GV_DataTable.DataSource = dal.RunSqlDataTable("select * from Manage_Table"); this.GV_DataTable.DataBind(); dal.Dispose(); }
更正:
由於對Dictionary 和靜態變量不夠了解,造成了一個錯誤,現在已經改正。原先想使用Dictionary 來避免switch(根據不同的數據庫類型創建不同的實例),現在還得改用 switch的方式來創建實例。
下載文件已經更新。
修改後的代碼
public DbParameter CreateParameter(string myParameterName) { DbParameter par = null; switch (this.DataType) { case "1": par = new System.Data.SqlClient.SqlParameter(); break; case "2": par = new System.Data.OleDb.OleDbParameter(); break; case "3": par = new System.Data.Odbc.OdbcParameter(); break; } par.ParameterName = myParameterName; return par; }