Enterprise Library2.0(1):Data Access Application Block學習

本文轉載自:http://www.cnblogs.com/terrylee/archive/2006/03/14/350026.html 作者:Terrylee 轉載請註明該聲明。

644df077b45fe418552fd271330a434b.jpe

Data Access Application Block提供了通用的數據訪問的功能,隨着2.0版本的推出有了很大變化。

一.改進

DAAB1.1裏面我們知道Database方法返回或者創建一個DBCommandWrapper對象,而在DAAB2.0裏面移除了DBCommandWrapper類,用ADO.NET2.0裏面的DBCommand類代替實現類似的功能,這樣使得DAAB跟我們的.NET類庫的結合更加緊密,回憶一下我們在1.1裏面用DBCommandWrapper來訪問數據時的代碼:

None.gifDatabase db  =  DatabaseFactory.CreateDatabase();
None.gif
None.gifDBCommandWrapper dbCommand 
=  db.GetStoredProcCommandWrapper( " GetProductsByCategory " );
None.gif
None.gifdbCommand.AddInParameter(
" CategoryID " , DbType.Int32, Category);
None.gif
None.gifDataSet productDataSet 
=  db.ExecuteDataSet(dbCommand);

而用了新的DBCommand類之後則變成了:

None.gifDatabase db  =  DatabaseFactory.CreateDatabase();
None.gif
None.gifDbCommand dbCommand 
=  db.GetStoredProcCommand( " GetProductsByCategory " ); 
None.gif
None.gifdb.AddInParameter(dbCommand, 
" CategoryID " , DbType.Int32, Category);
None.gif
None.gifDataSet productDataSet 
=  db.ExecuteDataSet(dbCommand);

數據庫連接字符串在我們基於數據庫的開發永遠是少不了的,但是在DAAB1.1下,它所使用的字符串跟我們在.NET類庫中使用的連接字符串卻是不能共享的,它們分別保存在不同的位置。而在2.0Data Access Application Block使用了ADO.NET2.0裏面<connectionStrings>配置區,這樣帶來的一個好處是連接字符串可以在Application Block和自定義的.NET類之間共享使用該配置區,如:

None.gif< connectionStrings >
None.gif        
< add
None.gif            
name ="DataAccessQuickStart"  
None.gif            providerName
="System.Data.SqlClient"
None.gif            connectionString
="server=(local)\SQLEXPRESS;database=EntLibQuickStarts;Integrated Security=true"   />
None.gif
</ connectionStrings >

.NET2.0下,泛型編程已經成爲了一個核心,而2.0版的DAAB中也新增了一個GenericDatabase對象。DAAB中雖然已經包含了SqlDatabaseOrcaleDatabase,但是如果我們需要使用其他的像DB2等數據庫時,就需要用到GenericDatabase,它可以用於任何.NET類庫中的數據提供者,包括OdbcProviderOleDbProvider

二.使用示例

DAAB2.0的配置非常簡單,主要有以下幾方面的配置:

配置連接字符串

32b9f81f10607d3891e4d86fe77e5cb8.jpe

配置默認數據庫

1052ccc25666b6672a5222b6edbc062b.jpe

添加相關的命名空間:

None.gifusing  Microsoft.Practices.EnterpriseLibrary.Data;
None.gif
using  System.Data;

使用Data Access Application Block進行數據的讀取和操作,一般分爲三步:

1.創建Database對象

2.提供命令參數,如果需要的話

3.執行命令

下面分別看一下DataAccessQuickStart中提供的一些例子:

執行靜態的SQL語句

None.gifpublic   string  GetCustomerList()
ExpandedBlockStart.gifContractedBlock.gif
222530190136c9c4cfd237cc0d5cff99.jpe {
InBlock.gif
// 創建Database對象
InBlock.gif
Database db = DatabaseFactory.CreateDatabase();
InBlock.gif
// 使用SQL語句創建DbCommand對象
InBlock.gif
string sqlCommand = "Select CustomerID, Name, Address, City, Country, PostalCode " +
InBlock.gif    
"From Customers";
InBlock.gifDbCommand dbCommand 
= db.GetSqlStringCommand(sqlCommand);
InBlock.gif
InBlock.gifStringBuilder readerData 
= new StringBuilder();
InBlock.gif
InBlock.gif
// 調用ExecuteReader方法
InBlock.gif
using (IDataReader dataReader = db.ExecuteReader(dbCommand))
ExpandedSubBlockStart.gifContractedSubBlock.gif
222530190136c9c4cfd237cc0d5cff99.jpe{
InBlock.gif    
while (dataReader.Read())
ExpandedSubBlockStart.gifContractedSubBlock.gif    
222530190136c9c4cfd237cc0d5cff99.jpe{
InBlock.gif        
// Get the value of the 'Name' column in the DataReader
InBlock.gif
        readerData.Append(dataReader["Name"]);
InBlock.gif        readerData.Append(Environment.NewLine);
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
return readerData.ToString();
ExpandedBlockEnd.gif}

執行存儲過程並傳遞參數,返回DataSet

None.gifpublic  DataSet GetProductsInCategory( int  Category)
ExpandedBlockStart.gifContractedBlock.gif
222530190136c9c4cfd237cc0d5cff99.jpe {
InBlock.gif    
// Create the Database object, using the default database service. The
InBlock.gif    
// default database service is determined through configuration.
InBlock.gif
    Database db = DatabaseFactory.CreateDatabase();
InBlock.gif
InBlock.gif    
string sqlCommand = "GetProductsByCategory";
InBlock.gif    DbCommand dbCommand 
= db.GetStoredProcCommand(sqlCommand);
InBlock.gif
InBlock.gif    
// Retrieve products from the specified category.
InBlock.gif
    db.AddInParameter(dbCommand, "CategoryID", DbType.Int32, Category);
InBlock.gif
InBlock.gif    
// DataSet that will hold the returned results        
InBlock.gif
    DataSet productsDataSet = null;
InBlock.gif
InBlock.gif    productsDataSet 
= db.ExecuteDataSet(dbCommand);
InBlock.gif
InBlock.gif    
// Note: connection was closed by ExecuteDataSet method call 
InBlock.gif

InBlock.gif    
return productsDataSet;
ExpandedBlockEnd.gif}

利用DataSet更新數據

None.gifpublic   int  UpdateProducts()
ExpandedBlockStart.gifContractedBlock.gif
222530190136c9c4cfd237cc0d5cff99.jpe {
InBlock.gif    
// Create the Database object, using the default database service. The
InBlock.gif    
// default database service is determined through configuration.
InBlock.gif
    Database db = DatabaseFactory.CreateDatabase();
InBlock.gif
InBlock.gif    DataSet productsDataSet 
= new DataSet();
InBlock.gif
InBlock.gif    
string sqlCommand = "Select ProductID, ProductName, CategoryID, UnitPrice, LastUpdate " +
InBlock.gif        
"From Products";
InBlock.gif    DbCommand dbCommand 
= db.GetSqlStringCommand(sqlCommand);
InBlock.gif
InBlock.gif    
string productsTable = "Products";
InBlock.gif
InBlock.gif    
// Retrieve the initial data
InBlock.gif
    db.LoadDataSet(dbCommand, productsDataSet, productsTable);
InBlock.gif
InBlock.gif    
// Get the table that will be modified
InBlock.gif
    DataTable table = productsDataSet.Tables[productsTable];
InBlock.gif
InBlock.gif    
// Add a new product to existing DataSet
ExpandedSubBlockStart.gifContractedSubBlock.gif
    DataRow addedRow = table.Rows.Add(new object[] 222530190136c9c4cfd237cc0d5cff99.jpe{DBNull.Value, "New product"1125});
InBlock.gif
InBlock.gif    
// Modify an existing product
InBlock.gif
    table.Rows[0]["ProductName"= "Modified product";
InBlock.gif
InBlock.gif    
// Establish our Insert, Delete, and Update commands
InBlock.gif
    DbCommand insertCommand = db.GetStoredProcCommand("AddProduct");
InBlock.gif    db.AddInParameter(insertCommand, 
"ProductName", DbType.String, "ProductName", DataRowVersion.Current);
InBlock.gif    db.AddInParameter(insertCommand, 
"CategoryID", DbType.Int32, "CategoryID", DataRowVersion.Current);
InBlock.gif    db.AddInParameter(insertCommand, 
"UnitPrice", DbType.Currency, "UnitPrice", DataRowVersion.Current);
InBlock.gif
InBlock.gif    DbCommand deleteCommand 
= db.GetStoredProcCommand("DeleteProduct");
InBlock.gif    db.AddInParameter(deleteCommand, 
"ProductID", DbType.Int32, "ProductID", DataRowVersion.Current);
InBlock.gif
InBlock.gif    DbCommand updateCommand 
= db.GetStoredProcCommand("UpdateProduct");
InBlock.gif    db.AddInParameter(updateCommand, 
"ProductID", DbType.Int32, "ProductID", DataRowVersion.Current);
InBlock.gif    db.AddInParameter(updateCommand, 
"ProductName", DbType.String, "ProductName", DataRowVersion.Current);
InBlock.gif    db.AddInParameter(updateCommand, 
"LastUpdate", DbType.DateTime, "LastUpdate", DataRowVersion.Current);
InBlock.gif
InBlock.gif    
// Submit the DataSet, capturing the number of rows that were affected
InBlock.gif
    int rowsAffected = db.UpdateDataSet(productsDataSet, "Products", insertCommand, updateCommand,
InBlock.gif                                        deleteCommand, UpdateBehavior.Standard);
InBlock.gif
InBlock.gif    
return rowsAffected;
InBlock.gif
ExpandedBlockEnd.gif}

通過ID獲取記錄詳細信息

None.gifpublic   string  GetProductDetails( int  productID)
ExpandedBlockStart.gifContractedBlock.gif
222530190136c9c4cfd237cc0d5cff99.jpe {
InBlock.gif    
// Create the Database object, using the default database service. The
InBlock.gif    
// default database service is determined through configuration.
InBlock.gif
    Database db = DatabaseFactory.CreateDatabase();
InBlock.gif
InBlock.gif    
string sqlCommand = "GetProductDetails";
InBlock.gif    DbCommand dbCommand 
= db.GetStoredProcCommand(sqlCommand);
InBlock.gif
InBlock.gif    
// Add paramters
InBlock.gif    
// Input parameters can specify the input value
InBlock.gif
    db.AddInParameter(dbCommand, "ProductID", DbType.Int32, productID);
InBlock.gif    
// Output parameters specify the size of the return data
InBlock.gif
    db.AddOutParameter(dbCommand, "ProductName", DbType.String, 50);
InBlock.gif    db.AddOutParameter(dbCommand, 
"UnitPrice", DbType.Currency, 8);
InBlock.gif
InBlock.gif    db.ExecuteNonQuery(dbCommand);
InBlock.gif
InBlock.gif    
// Row of data is captured via output parameters
InBlock.gif
    string results = string.Format(CultureInfo.CurrentCulture, "{0}, {1}, {2:C} ",
InBlock.gif                                   db.GetParameterValue(dbCommand, 
"ProductID"),
InBlock.gif                                   db.GetParameterValue(dbCommand, 
"ProductName"),
InBlock.gif                                   db.GetParameterValue(dbCommand, 
"UnitPrice"));
InBlock.gif
InBlock.gif    
return results;
ExpandedBlockEnd.gif}

XML格式返回數據

None.gifpublic   string  GetProductList()
ExpandedBlockStart.gifContractedBlock.gif
222530190136c9c4cfd237cc0d5cff99.jpe {
InBlock.gif    
// Use a named database instance that refers to a SQL Server database.
InBlock.gif
    SqlDatabase dbSQL = DatabaseFactory.CreateDatabase() as SqlDatabase;
InBlock.gif
InBlock.gif    
// Use "FOR XML AUTO" to have SQL return XML data
InBlock.gif
    string sqlCommand = "Select ProductID, ProductName, CategoryID, UnitPrice, LastUpdate " +
InBlock.gif        
"From Products FOR XML AUTO";
InBlock.gif    DbCommand dbCommand 
= dbSQL.GetSqlStringCommand(sqlCommand);
InBlock.gif
InBlock.gif    XmlReader productsReader 
= null;
InBlock.gif    StringBuilder productList 
= new StringBuilder();
InBlock.gif
InBlock.gif    
try
ExpandedSubBlockStart.gifContractedSubBlock.gif    
222530190136c9c4cfd237cc0d5cff99.jpe{
InBlock.gif        productsReader 
= dbSQL.ExecuteXmlReader(dbCommand);
InBlock.gif
InBlock.gif        
// Iterate through the XmlReader and put the data into our results.
InBlock.gif
        while (!productsReader.EOF)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
222530190136c9c4cfd237cc0d5cff99.jpe{
InBlock.gif            
if (productsReader.IsStartElement())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
222530190136c9c4cfd237cc0d5cff99.jpe{
InBlock.gif                productList.Append(productsReader.ReadOuterXml());
InBlock.gif                productList.Append(Environment.NewLine);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif    
222530190136c9c4cfd237cc0d5cff99.jpe{
InBlock.gif      
// Close the Reader.
InBlock.gif
      if (productsReader != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif      
222530190136c9c4cfd237cc0d5cff99.jpe{
InBlock.gif          productsReader.Close();
ExpandedSubBlockEnd.gif      }

InBlock.gif      
InBlock.gif      
// Explicitly close the connection. The connection is not closed
InBlock.gif      
// when the XmlReader is closed.
InBlock.gif
      if (dbCommand.Connection != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif      
222530190136c9c4cfd237cc0d5cff99.jpe{
InBlock.gif        dbCommand.Connection.Close();
ExpandedSubBlockEnd.gif      }
  
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
return productList.ToString();
ExpandedBlockEnd.gif}

使用事務

None.gifpublic   bool  Transfer( int  transactionAmount,  int  sourceAccount,  int  destinationAccount)
ExpandedBlockStart.gifContractedBlock.gif
222530190136c9c4cfd237cc0d5cff99.jpe {
InBlock.gif    
bool result = false;
InBlock.gif    
InBlock.gif    
// Create the Database object, using the default database service. The
InBlock.gif    
// default database service is determined through configuration.
InBlock.gif
    Database db = DatabaseFactory.CreateDatabase();
InBlock.gif
InBlock.gif    
// Two operations, one to credit an account, and one to debit another
InBlock.gif    
// account.
InBlock.gif
    string sqlCommand = "CreditAccount";
InBlock.gif    DbCommand creditCommand 
= db.GetStoredProcCommand(sqlCommand);
InBlock.gif
InBlock.gif    db.AddInParameter(creditCommand, 
"AccountID", DbType.Int32, sourceAccount);
InBlock.gif    db.AddInParameter(creditCommand, 
"Amount", DbType.Int32, transactionAmount);
InBlock.gif
InBlock.gif    sqlCommand 
= "DebitAccount";
InBlock.gif    DbCommand debitCommand 
= db.GetStoredProcCommand(sqlCommand);
InBlock.gif
InBlock.gif    db.AddInParameter(debitCommand, 
"AccountID", DbType.Int32, destinationAccount);
InBlock.gif    db.AddInParameter(debitCommand, 
"Amount", DbType.Int32, transactionAmount);
InBlock.gif
InBlock.gif    
using (DbConnection connection = db.CreateConnection())
ExpandedSubBlockStart.gifContractedSubBlock.gif    
222530190136c9c4cfd237cc0d5cff99.jpe{
InBlock.gif        connection.Open();
InBlock.gif        DbTransaction transaction 
= connection.BeginTransaction();
InBlock.gif
InBlock.gif        
try
ExpandedSubBlockStart.gifContractedSubBlock.gif        
222530190136c9c4cfd237cc0d5cff99.jpe{
InBlock.gif            
// Credit the first account
InBlock.gif
            db.ExecuteNonQuery(creditCommand, transaction);
InBlock.gif            
// Debit the second account
InBlock.gif
            db.ExecuteNonQuery(debitCommand, transaction);
InBlock.gif
InBlock.gif            
// Commit the transaction
InBlock.gif
            transaction.Commit();
InBlock.gif            
InBlock.gif            result 
= true;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
catch
ExpandedSubBlockStart.gifContractedSubBlock.gif        
222530190136c9c4cfd237cc0d5cff99.jpe{
InBlock.gif            
// Rollback transaction 
InBlock.gif
            transaction.Rollback();
ExpandedSubBlockEnd.gif        }

InBlock.gif        connection.Close();
InBlock.gif        
InBlock.gif        
return result;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

三.常見功能

1.創建Database對象

創建一個默認的Database對象

None.gifDatabase dbSvc  =  DatabaseFactory.CreateDatabase();

默認的數據庫在配置文件中:

None.gif< dataConfiguration  defaultDatabase ="DataAccessQuickStart"   />

創建一個實例Database對象

None.gif//  Use a named database instance that refers to an arbitrary database type, 
None.gif
//  which is determined by configuration information.
None.gif
Database myDb  =  DatabaseFactory.CreateDatabase( " DataAccessQuickStart " );

創建一個具體的類型的數據庫對象

None.gif//  Create a SQL database.
None.gif
SqlDatabase dbSQL  =  DatabaseFactory.CreateDatabase( " DataAccessQuickStart " as  SqlDatabase;

2.創建DbCommand對象

靜態的SQL語句創建一個DbCommand

None.gifDatabase db  =  DatabaseFactory.CreateDatabase();
None.gif
string  sqlCommand  =   " Select CustomerID, LastName, FirstName From Customers " ;
None.gifDbCommand dbCommand 
=  db.GetSqlStringCommand(sqlCommand);

存儲過程創建一個DbCommand

None.gifDatabase db  =  DatabaseFactory.CreateDatabase();
None.gifDbCommand dbCommand 
=  db.GetStoredProcCommand( " GetProductsByCategory " );

3.管理對象

當連接對象打開後,不需要再次連接

None.gifDatabase db  =  DatabaseFactory.CreateDatabase();
None.gif
string  sqlCommand  =   " Select ProductID, ProductName From Products " ;
None.gifDbCommand dbCommand 
=  db.GetSqlStringCommand(sqlCommand); 
None.gif
//  No need to open the connection; just make the call.
None.gif
DataSet customerDataSet  =  db.ExecuteDataSet(dbCommand);

使用Using及早釋放對象

None.gifDatabase db  =  DatabaseFactory.CreateDatabase();
None.gifDbCommand dbCommand 
=  db.GetSqlStringCommand( " Select Name, Address From Customers " );
None.gif
using  (IDataReader dataReader  =  db.ExecuteReader(dbCommand))
ExpandedBlockStart.gifContractedBlock.gif
222530190136c9c4cfd237cc0d5cff99.jpe {
InBlock.gif
// Process results
ExpandedBlockEnd.gif
}

4.參數處理

Database類提供瞭如下的方法,用於參數的處理:

AddParameter. 傳遞參數給存儲過程
AddInParameter.
傳遞輸入參數給存儲過程
AddOutParameter.
傳遞輸出參數給存儲過程
GetParameterValue.
得到指定參數的值
SetParameterValue.
設定參數值

使用示例如下:

None.gifDatabase db  =  DatabaseFactory.CreateDatabase();
None.gif
string  sqlCommand  =   " GetProductDetails " ;
None.gifDbCommand dbCommand 
=  db.GetStoredProcCommand(sqlCommand);
None.gifdb.AddInParameter(dbCommand, 
" ProductID " , DbType.Int32,  5 );
None.gifdb.AddOutParameter(dbCommand, 
" ProductName " , DbType.String,  50 );
None.gifdb.AddOutParameter(dbCommand, 
" UnitPrice " , DbType.Currency,  8 );

None.gifDatabase db  =  DatabaseFactory.CreateDatabase();
None.gifDbCommand insertCommand 
=  db.GetStoredProcCommand( " AddProduct " );
None.gifdb.AddInParameter(insertCommand, 
" ProductName " , DbType.String,  " ProductName " , DataRowVersion.Current);
None.gifdb.AddInParameter(insertCommand, 
" CategoryID " , DbType.Int32,  " CategoryID " , DataRowVersion.Current);
None.gifdb.AddInParameter(insertCommand, 
" UnitPrice " , DbType.Currency,  " UnitPrice " , DataRowVersion.Current);

四.使用場景

DAAB2.0是對ADO.NET2.0的補充,它允許你使用相同的數據訪問代碼來支持不同的數據庫,您通過改變配置文件就在不同的數據庫之間切換。目前雖然只提供SQLServerOracle的支持,但是可以通過GenericDatabaseADO.NET 2.0下的DbProviderFactory對象來增加對其他數據庫的支持。如果想要編寫出來的數據庫訪問程序具有更好的移植性,則DAAB2.0是一個不錯的選擇,但是如果您想要針對特定數據庫的特性進行編程,就要用ADO.NET了。

參考:Enterprise Libaray –January 2006幫助文檔及QuickStart

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章