出處:http://www.csharp-corner.com
willsound(翻譯)
我收到過好多Email來問我如何用一個通用的資料提供者(data provider)在不失自然資料提供者(native data provider)穩定而強大功能的前提下來訪問不同的資料來源(data sources).一個小夥子甚至問我能不能寫一些代碼在程式運行時指定資料提供者(data provider)。
緒論:
ADO.net對於不同的資料來源提供了不同的資料提供者,三個通用的資料提供者分別是OLE DB, SQL, and ODBC。使用不同資料提供者的用意就在於可以針對不同的資料來源提供最強大且穩定的資料訪問技術。例如,當你訪問Access資料庫時採用OLE DB data provider這是最有效方法,但是如果你採用ODBC data provider時,它是建在OLE DB data provider基礎上的,所以效率就會打折扣。
實際上,所有的資料提供者類(data provider classes),比如串連(connection),命令(command),資料配接器(data adapter)和資料讀取者(data reader)都是從某一特定介面繼承的。我希望寫篇文章深入的討論這些,但這要花費我很多天的時間。
總之,我的這篇文章的主要問題是如何寫一個通用的類能夠在運行時根據使用者的選擇而分別採用OLE DB, SQL, and ODBC data providers訪問資料來源。
介面模型:
每一種資料提供者都實現了一些介面(interfaces),這些介面都定義在System.Data名字空間(namespace)裡面。例如SqlConnection, OleDbConnection, and OdbcConnection類就是從IdbConnection介面繼承下來的。類似於connection類,其它的ADO.net組件像DataAdapter, DataReader, Command也都是從某個介面繼承下來的。
你們就將使用這些介面來實現通用資料訪問類。我不打算去寫所有的這些功能,但我會給你們如何擴充這些功能提供一個好的想法。
下面的代碼1展現了一個GenericAdoNetComp類,它提供了二個方法,GetConnection 和GetDataAdapter。這兩個方法都是從使用者提供提供的資訊關基於connection讀取資訊,這二個方法將返回所希望的輸出。下面就是這兩個方法的定義
public IDbConnection GetConnection(int connType, string connString)
public IDbDataAdapter GetDataAdapter(int connType, string connString, string sql)
正如你你所見,我們用IdBConnection取代connection和一個資料提供者相連,方法將返回IdbConnection.從下面的代碼1中你們將看到我們根據使用者在運行時提供的連結種類型別參數(connection type argument)來產生SqlConnection, OleDbConnection, or或者OdbcConnection。
//代碼1
using System;
using System.Data;
using System.Data.Common;
using System.Data.OleDb;
using System.Data.SqlClient;
using Microsoft.Data.Odbc;
namespace GenericDataAccessApp
{
public class GenericAdoNetComp
{
private IDbConnection idbConn = null;
private IDbDataAdapter idbAdapter = null;
private DbDataAdapter dbAdapter = null;
private IDataReader iReader = null;
public GenericAdoNetComp()
{
}
// GetConnection returns IDbConnection
public IDbConnection GetConnection(int connType,
string connString)
{
switch(connType)
{
case 1: // OleDb Data Provider
idbConn = new OleDbConnection(connString);
break;
case 2: // Sql Data Provider
idbConn = new SqlConnection(connString);
break;
case 3: // ODBC Data Provider
idbConn = new OdbcConnection(connString);
break;
// case 3: // Add your custom data provider
default:
break;
}
return idbConn;
}
// GetDataAdapter returns IDbDataAdapter
public IDbDataAdapter GetDataAdapter(int connType,
string connString, string sql)
{
switch(connType)
{
case 1: // OleDb Data Provider
idbAdapter = new OleDbDataAdapter(sql, connString);
break;
case 2: // Sql Data Provider
idbAdapter = new SqlDataAdapter(sql, connString);
break;
case 3: // ODBC Data Provider
idbAdapter = new OdbcDataAdapter(sql, connString);
break;
// case 3: // Add your custom data provider
default:
break;
}
return idbAdapter;
}
}
}
使用者應用程式:
現在,就讓我們來看看如何在windows應用程式裡面使用這個類。為了進行測試,我們建立了一個windows應用程式,在表單上我們放上三個radio buttons控制項,一個button控制項,一個Group Box控制項和一個DataGrid 控制項。
從表單的部局上我們可以猜的出,此程式可以根據使用者的選擇來確定使用哪種資料提供者。正如你在上圖所看到的,表單上有三個選項,你可以選擇其一,然後單擊connect按鈕。根據選擇的連線類型,連接到資料庫關且向DataGrid中填充資料。
在我的應用程式裡面,我定義了下面的變數。
private string connString, sql;
IDbConnection conn = null;
IDbDataAdapter adapter = null;
下面就是connect按鈕的的代碼,在哪裡建立了一個GenericAdoNetCom類的執行個體,並且調用它的GetConnection 和 GetDataAdapter 方法。一但你提供了一個DataAdapter,你只需簡單的調用Fill和Update方法來讀取和寫入資料。
private void ConnectBtn_Click(object sender, System.EventArgs e)
{
GenericAdoNetComp genDP = new GenericAdoNetComp();
sql = "SELECT * FROM Employees";
if(radioButton1.Checked)
{
connString =
"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c://Northwind.mdb";
conn = genDP.GetConnection(1, connString);
adapter = genDP.GetDataAdapter(1, connString, sql);
}
else if (radioButton2.Checked)
{
connString =
"Data Source=MCB;Initial Catalog=Northwind;user id=sa;password=;";
conn = genDP.GetConnection(2, connString);
adapter = genDP.GetDataAdapter(2, connString, sql);
}
else if (radioButton3.Checked)
{
// Construct your connection string here
conn = genDP.GetConnection(3, connString);
adapter = genDP.GetDataAdapter(3, connString, sql);
}
try
{
conn.Open();
// Fill a DataSet
DataSet ds = new DataSet();
adapter.Fill(ds);
dataGrid1.DataSource = ds.Tables[0].DefaultView;
}
catch(Exception exp)
{
MessageBox.Show(exp.Message);
}
finally
{
conn.Close();
}
}
總結:
在這篇文章裡,我們討論了如何寫一個通用資料訪問類。你可以擴充用ADO.net中其實的組組件來這個類的功能,我一直努力使這篇文章通俗易懂。