熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

ASP.NET2.0—— 實現數據訪問層

2022-06-13   來源: .NET編程 

  在文章重點對AdventureWorks貿易系統的基本概況數據庫設計和CLR存儲過程進行了講解本文主要說明該系統的數據訪問層實現方法

   實現數據訪問層

  本節將講解數據訪問層的實現該層包括與AdventureWorks數據庫通信的所有必要類和方法首先使用Visual Studio 創建新的Visual C#類庫項目AdventureWorksTraderDataAccess當這個項目創建後可修改默認類名稱為ProductCategoryDB示例說明了ProductCategoryDB類的實現代碼

  示例實現ProductCategoryDB類

    using System;
using SystemData;
using SystemDataCommon;
using SystemDataSqlClient;
using SystemCollectionsGeneric;
using SystemText;
using AdventureWorksTraderEntities;
using MicrosoftPracticesEnterpriseLibraryData;

namespace AdventureWorksTraderDataAccess
{
public class ProductCategoryDB
{
private DataColumnMapping[] mappings = new DataColumnMapping[] { new DataColumnMapping(ProductCategoryID ProductCategoryID) new DataColumnMapping(Name Name) new DataColumnMapping(rowguid Rowguid) new DataColumnMapping(ModifiedDate ModifiedDate) };

public IList<ProductCategory> GetProductCategories()
{
IList<ProductCategory> list = new List<ProductCategory>();
Database db = DatabaseFactoryCreateDatabase();
string storedProcedureName = GetProductCategories;
DbCommand dbCommand = dbGetStoredProcCommand(storedProcedureName);
using (IDataReader reader = dbExecuteReader(dbCommand))
{
while (readerRead())
{
ProductCategory temp = new ProductCategory();
ProductCategory category = (ProductCategory)DataAccessHelperPopulateEntity(temp mappings reader);
listAdd(category);
}
}
return list;
}
}
}     
     ProductCategoryDB類僅包括GetProductCategories方法該方法返回ProductCategory表中包括的所有類別在內部GetProductCategories()方法利用EntLib數據訪問塊來執行GetProductCategories存儲過程接著將輸出轉換為由多個ProductCategory對象組成的泛型集合GetProductCategories()方法中的構造塊實現了如下功能

  使用EntLib數據訪問塊實現數據訪問
    使用泛型工具將輸出轉換為泛型集合
    實現ProductCategory項目
    使用泛型集合方式傳送數據
    以下內容詳細說明這些構建塊

  使用數據訪問塊實現數據訪問

  ADONET提供了豐富的能夠以多種方式獲取和顯示數據的功能即使使用ADONET提供的靈活性但有時候開發人員仍然會發現自己一遍又一遍的在重復編寫相同的代碼例如每個數據驅動的應用程序都需要訪問數據庫那麼開發人員則要編寫代碼來連接數據庫打開數據庫執行SQL語句或者存儲過程在客戶應用程序中獲取結果關閉數據庫開發人員將被迫在所開發的幾乎任何應用程序中編寫這些重復性代碼而這對於核心業務用戶沒有任何真正的價值在開發的每個應用程序中可能唯一可能不同的代碼是SQL語句或者存儲過程名稱命令參數和連接字符串只要能夠參數化這些變量就能夠將多數重復性代碼抽象到可重用類中那麼在多個應用程序中都能夠使用這些類微軟已經以EntLib數據訪問塊的形式完成了這件事本實例將使用數據訪問塊來與數據庫交流

  什麼是數據訪問塊

  正如前文提到的當開發數據庫應用程序時數據訪問塊用於完成開發人員所面對的多數常見任務數據訪問塊通過提供一組封裝的方法能夠大大簡化訪問數據庫的多數常見方法每個方法都封裝了實現返回數據所需的邏輯同時還能夠管理數據庫連接另外通過編寫能夠跨不同數據庫類型使用而不必修改代碼的數據訪問代碼數據訪問塊對ADONET 提供了補充這些類包括了提供給專用數據庫實現功能(例如參數處理和游標)的代碼

  此外數據訪問塊還為SQL Server和Oracle提供了專用的繼承類另外GenericDatabase類還允許通過任何經過配置的ADONET 中的DbProviderFactory對象使用應用程序塊開發人員通過添加實現新的包括專用數據庫功能的數據庫類型或者提供了現有數據庫的自定義實現來擴展應用程序塊

  數據訪問塊版本較斑斑有了革命性改進其設計重新設計用於使用ADONET 功能開發人員可以從/downloads下載和查找EntLib數據訪問塊

  使用數據訪問塊的步驟

  為了使用數據訪問塊需要執行以下步驟
    在解決方案中添加對MicrosoftPracticesEnterpriseLibraryCommondll和MicrosoftPracticesEnterpriseLibraryDatadll程序集的引用使用添加應用選項導航到<驅動器名稱>:\Program Files\Microsoft Enterprise Library January \bin文件夾中可實現添加對這些程序集的引用

   在nfignfig或者自定義配置文件中添加必要的配置項為此將以下<configSections>元素添加到<configuration>元素下
    
     <configSections>
<section name=dataConfiguration type=MicrosoftPracticesEnterpriseLibraryDataConfigurationDatabaseSettings MicrosoftPracticesEnterpriseLibraryData />
</configSections>
    
    然後還要將<dataConfiguration>元素直接添加到<configuration>元素下如下所示
    
     <dataConfiguration defaultDatabase=AdventureWorksDB/>    
    本實例將AdventureWorksDB數據庫標記為默認數據庫其在<connectionStrings>元素中獨立聲明

    <connectionStrings>
<add name=AdventureWorksDB providerName=SystemDataSqlClient
connectionString=server=localhost; database=AdventureWorks; UID=user; PWD=word; />
</connectionStrings>
    
    在代碼中導入數據訪問塊的核心命名空間MicrosoftPractices EnterpriseLibraryData
    在核心命名空間下開始編寫類代碼
    既然讀者已經了解了EntLib數據訪問塊的基礎知識那麼下面可以學習一下數據訪問塊中的關鍵類

  Database對象

  任何時候使用數據訪問塊首先必須處理Database類Database類表示數據庫以及在數據庫中執行命令的方法Database對象公開了以下方法使用這些方法能夠對數據庫執行CRUD操作
    
   

    
    既然讀者已經了解了Database類中的方法那麼就可以重新考慮數據訪問層ProductCategory類的GetProductCategories()方法以便理解集成數據訪問塊的方法

    IList<ProductCategory> list = new List<ProductCategory>();
Database db = DatabaseFactoryCreateDatabase();
string storedProcedureName = GetProductCategories;
DbCommand dbCommand = dbGetStoredProcCommand(storedProcedureName);
using (IDataReader reader = dbExecuteReader(dbCommand))
    
    首先調用DatabseFactory類的CreateDatabase()方法以獲取Database對象實例正如名稱暗示的那樣DatabaseFactory類包括了創建Database對象的工廠方法注意CreateDatabase()是一個重載方法當調用無參數的CreateDatabase()方法時該方法將返回默認數據庫為此可在nfig文件中將defaultDatabase屬性設置為適當的數據庫配置鍵如下所示

    <dataConfiguration defaultDatabase = AdventureWorksDB />    
    當創建Database對象實例後接著可調用GetStoredCommand()方法以便生成ADONET 的DBCommand對象此後將DbCommand作為參數傳遞給ExecuteReader()方法並利用該方法執行存儲過程 

  使用泛型程序實現輸出轉換

  當獲取了作為輸出的SqlDataReader對象後下一步是將輸出內容轉換為可發送到業務邏輯層的泛型集合
    GetProductCategories()方法利用輔助類DataAccessHelper(如示例所示)將SqlDataReader對象內容轉換為對象

  示例實現DataAccessHelper類

    using System;
using SystemData;
using SystemDataSqlClient;
using SystemConfiguration;
using SystemDataCommon;
using SystemReflection;
using SystemCollections;

namespace AdventureWorksTraderDataAccess
{
public class DataAccessHelper
{
static public object PopulateEntity(object entity DataColumnMapping[] mappings IDataReader reader)
{
foreach (DataColumnMapping mapping in mappings)
{
int ordinalPosition = ;
try
{
ordinalPosition = readerGetOrdinal(mappingSourceColumn);
}
catch (IndexOutOfRangeException ex)
{
throw new PropertyColumnMappingException(mappingSourceColumn +
is not a valid SourceColumn ex);
}
object propertyValue = readerGetValue(ordinalPosition);
if (propertyValue != DBNullValue)
{
if (mappingDataSetColumn == ID)
{
Nullable<int> tempValue = (int)propertyValue;
propertyValue = tempValue;
}
object[] param = { propertyValue };
try
{
entityGetType()InvokeMember(mappingDataSetColumn BindingFlagsSetProperty | BindingFlagsInstance | BindingFlagsPublic | BindingFlagsNonPublic | BindingFlagsFlattenHierarchy | BindingFlagsStatic null entity param);
}
catch (Exception e)
{
throw new PropertyColumnMappingException
(GetPropertyColumnMappingExceptionMessage(mapping) e);
}
}
}
return entity;
}

private static string GetPropertyColumnMappingExceptionMessage
(DataColumnMapping mapping)
{
return Could not populate + mappingDataSetColumn +
property from the + mappingSourceColumn + database column;
}
}
}     
    在GetProductCategories()方法內部首先聲明了一個DataColumnMapping數組該數組中包括ProductCategory表列與ProductCategory對象屬性之間的所有映射信息

    private DataColumnMapping[] mappings = new DataColumnMapping[] {
new DataColumnMapping(ProductCategoryID ProductCategoryID)
new DataColumnMapping(Name Name)
new DataColumnMapping(rowguid Rowguid)
new DataColumnMapping(ModifiedDate ModifiedDate)};
    
    當調用PopulateEntity()時需要提供ProductCategory對象實例DataColumnMapping數組以及包括執行存儲過程所得輸出的SqlDataReader對象
    
     ProductCategory category = (ProductCategory)DataAccessHelperPopulateEntity(temp mappings reader);    
    PopulateEntity()方法將SqlDataReader對象的每一行轉換為具有適當屬性值的ProductCategory對象 

   實現ProductCategory對象

  除了數據訪問和業務邏輯層組件之外本實例還包括另一個名為AdventureWorksTraderEntities的項目該項目公開了一組直接對應數據庫中實體的對象ProductCategory表對應的是ProductCategory類(如示例所示)該類可作為容器存儲與ProductCategory有關的數據

  示例實現ProductCategory類

    using System;
using SystemCollectionsGeneric;
using SystemText;
namespace AdventureWorksTraderEntities
{
[Serializable]
public class ProductCategory
{
private int _productCategoryID;
private string _name;
private Guid _rowguid;
private DateTime _modifiedDate;

public int ProductCategoryID
{
get { return _productCategoryID; }
set { _productCategoryID = value; }
}

public string Name
{
get { return _name; }
set { _name = value; }
}

public Guid Rowguid
{
get { return _rowguid; }
set { _rowguid = value; }
}

public DateTime ModifiedDate
{
get { return _modifiedDate; }
set { _modifiedDate = value; }
}
}
}
    
    正如看到的ProductCategory類如同一個占位符每個屬性都直接對應ProductCategory表中的一個列

  使用泛型集合

  讀者應該記得GetProductCategories()方法的返回值該值是ProductCategory對象的泛型集合以下代碼段專用於泛型集合

    while (readerRead())
{
ProductCategory temp = new ProductCategory();
ProductCategory category = (ProductCategory)
DataAccessHelperPopulateEntity(temp mappings reader);
listAdd(category);
}     
    在以上代碼中首先循環整個SqlDataReader對象然後將SqlDataReader對象的每一行都轉換為一個ProductCategory對象最後將ProductCategory對象添加到泛型集合中

  使用泛型可使得軟件組件中的代碼更加具有可重用性泛型是一種數據結構類型其中包含的代碼保持不變參數的數據類型能夠在使用時變化根據所提供的變量使用數據結構能夠適應不同的數據類型每次使用泛型時可自定義不同的數據類型而無需重寫任何內部代碼泛型允許類結構接口委托和方法將它們所存儲和操作的數據類型實現參數化

  在ASPNET頁面中GetProductCategories()返回的泛型集合直接綁定到ObjectDataSource控件當隨後講解本實例Web站點實現時將看到這些內容

   實現ProductSubcategoryDB類

  ProductSubcategoryDB類包括GetProductSubcategories()方法該方法根據產品類別返回所屬所有子類別的列表這個方法的實現非常類似於ProductCategoryGetProductCategories()示例列舉了ProductSubcategoryDB類的實現代碼

  示例實現ProductSubcategoryDB類
    
   

    using System;
using SystemData;
using SystemDataCommon;
using SystemDataSqlClient;
using SystemCollectionsGeneric;
using SystemText;
using AdventureWorksTraderEntities;
using MicrosoftPracticesEnterpriseLibraryData;

namespace AdventureWorksTraderDataAccess
{
public class ProductSubcategoryDB
{
private DataColumnMapping[] mappings = new DataColumnMapping[] {
new DataColumnMapping(ProductSubcategoryIDProductSubcategoryID)
new DataColumnMapping(ProductCategoryIDProductCategoryID)
new DataColumnMapping(NameName)
new DataColumnMapping(rowguidRowguid)
new DataColumnMapping(ModifiedDateModifiedDate)};

public IList<ProductSubcategory> GetProductSubCategories(int productCategoryID)
{

IList<ProductSubcategory> list = new List<ProductSubcategory>();
Database db = DatabaseFactoryCreateDatabase();
string storedProcedureName = GetProductSubcategories;
DbCommand dbCommand = dbGetStoredProcCommand(storedProcedureName);
dbAddInParameter(dbCommand productCategoryID DbTypeInt productCategoryID);
using (IDataReader reader = dbExecuteReader(dbCommand))
{
while (readerRead())
{
ProductSubcategory temp = new ProductSubcategory();
ProductSubcategory subCategory = (ProductSubcategory)DataAccessHelperPopulateEntity(temp mappings reader);
listAdd(subCategory);
}
}
return list;
}
}
}

  正如在示例看到的GetProductSubcategories()方法執行了GetProductSubcategories存儲過程該存儲過程接受productCategoryID參數此後的實現與GetProductCategories()方法相同
     

   實現ProductDB類

  正如名稱暗示的那樣示例所示的ProductDB類提供了專門訪問AdventureWorks數據庫中Product表的方法該類包括一個GetProducts()方法該方法根據提供的產品子類別ID返回所屬的所有產品

  示例實現ProdctDB類

    using System;
using SystemData;
using SystemDataCommon;
using SystemDataSqlClient;
using SystemCollectionsGeneric;
using SystemText;
using AdventureWorksTraderEntities;
using MicrosoftPracticesEnterpriseLibraryData;

namespace AdventureWorksTraderDataAccess
{
public class ProductDB
{
private DataColumnMapping[] mappings = new DataColumnMapping[] {
new DataColumnMapping(ProductIDProductID)
new DataColumnMapping(NameName)
new DataColumnMapping(ProductNumberProductNumber)
new DataColumnMapping(MakeFlagMakeFlag)
new DataColumnMapping(FinishedGoodsFlagFinishedGoodsFlag)
new DataColumnMapping(ColorColor)
new DataColumnMapping(SafetyStockLevelSafetyStockLevel)
new DataColumnMapping(ReorderPointReorderPoint)
new DataColumnMapping(StandardCostStandardCost)
new DataColumnMapping(ListPriceListPrice)
new DataColumnMapping(SizeSize)
new DataColumnMapping(SizeUnitMeasureCodeSizeUnitMeasureCode)
new DataColumnMapping(WeightUnitMeasureCodeWeightUnitMeasureCode)
new DataColumnMapping(WeightWeight)
new DataColumnMapping(DaysToManufactureDaysToManufacture)
new DataColumnMapping(ProductLineProductLine)
new DataColumnMapping(ClassClass)
new DataColumnMapping(StyleStyle)
new DataColumnMapping(ProductSubcategoryIDProductSubcategoryID)
new DataColumnMapping(ProductModelIDProductModelID)
new DataColumnMapping(SellStartDateSellStartDate)
new DataColumnMapping(SellEndDateSellEndDate)
new DataColumnMapping(DiscontinuedDateDiscontinuedDate)
new DataColumnMapping(rowguidRowguid)
new DataColumnMapping(ModifiedDateModifiedDate)};

public IList<Product> GetProducts(int productSubcategoryID)
{
IList<Product> list = new List<Product>();
Database db = DatabaseFactoryCreateDatabase();
string storedProcedureName = GetProducts;
DbCommand dbCommand = dbGetStoredProcCommand(storedProcedureName);
dbAddInParameter(dbCommand productSubCategoryID DbTypeInt
productSubcategoryID);
using (IDataReader reader = dbExecuteReader(dbCommand))
{
while (readerRead())
{
Product temp = new Product();
Product prod = (Product)DataAccessHelperPopulateEntity(temp mappings reader);
listAdd(prod);
}
}
return list;
}
}
}     
    GetProducts()方法執行了GetProducts存儲過程該存儲過程接受產品子類別ID作為參數同時基於該產品子類別返回所屬的所有產品列表

   實現業務邏輯層

  本節將關注業務邏輯層的實現該層封裝在類庫AdventureWorksTraderBiz中首先使用Visual Studio 創建新的名為AdventureWorksTraderBiz的Visual C#類庫項目此後添加上一節中創建的AdventureWorksTraderDataAccess的引用一旦項目創建後可將名為ProductCategoryBiz的類添加到項目中接著如示例所示修改代碼

  示例實現ProductCategoryBiz類

    using System;
using SystemCollectionsGeneric;
using SystemText;
using AdventureWorksTraderEntities;
using AdventureWorksTraderDataAccess;
using MicrosoftPracticesEnterpriseLibraryExceptionHandling;

namespace AdventureWorksTraderBiz
{
public class ProductCategoryBiz
{
public IList<ProductCategory> GetProductCategories()
{
try
{
ProductCategoryDB category = new ProductCategoryDB();
return categoryGetProductCategories();
}
catch (Exception ex)
{
bool rethrow = ExceptionPolicyHandleException(ex Log Only Policy);
if (rethrow)
{
throw;
}
return null;
}
}
}
}
    
    示例中所示的GetProductCategories()是主要方法該方法通過調用數據訪問層的GetProductCategories()方法來獲取所需數據業務邏輯層中生成的任何異常都在catch塊中通過EntLib異常處理塊處理這是下一節關注的重要問題

  由於業務邏輯層中剩余類(ProductSubcategoryBiz和ProductBiz)的實現與ProductCategoryBiz非常相似——除了它們調用的對應數據訪問層類的方法不同——所以將不會詳細講解剩余類然而讀者可從下載本實例的完整代碼
   快速浏覽企業庫中的異常處理塊

  開發人員編寫的每個NET應用程序都需要處理異常以及從異常中恢復微軟沒有采取在NET應用程序中創建測試和維護傳統代碼的方法而是創建了稱為企業庫異常處理塊(或者稱為EntLib異常處理塊)的應用程序塊該應用程序塊提供了實現異常處理所需的所有底層傳統代碼為達成本實例的目的將以統一高效的方式使用EntLib異常處理塊處理異常在討論異常處理塊與Web站點AdventureWorksTrader集成的所需步驟之前讀者需要理解異常處理塊的基礎知識

  異常處理塊中的關鍵組件

  為理解異常處理塊需要了解三個重要概念

  異常處理當在代碼中檢測到異常時處理異常的過程
    異常日志記錄異常的過程該過程包括將格式化異常發送到事件日志或者發送電子郵件異常處理塊利用日志和監測應用程序塊來實現此功能
    異常處理策略允許控制異常處理和使用外部配置文件記錄的行為而不用在代碼中實施這樣的規則換句話說開發人員可在一個策略文件中定義異常處理然後在不改變代碼的情況下在測試調試產品定型期間修改行為

  使用異常處理塊在代碼中檢測到異常時可做以下三件事情

  第一可把異常封裝為一個新的異常以便加入新的上下文信息或詳細信息當新的異常傳遞到調用堆棧時仍可通過InnerException屬性訪問原始的異常
    第二可用一個新的異常取代原有異常通常這樣做的目的是不想讓原始異常的詳細信息跨應用程序邊界傳遞
    第三能夠記錄異常當然也可結合使用封裝或取代的方法達成此目的或者記錄原始異常並把它傳遞到調用堆棧  

  使用異常處理塊

  通過浏覽/downloads和查找EntLib開發人員可下載EntLib緩存塊其中包括了異常處理塊在安裝完企業庫之後就可利用異常處理塊開始編寫代碼為正確使用異常處理塊需要遵循以下步驟

   在解決方案中分別添加對MicrosoftPracticesEnterpriseLibraryCommondll和MicrosoftPracticesEnterpriseLibraryExceptionHandlingdll程序集的引用為此可使用添加引用選項並定位到<驅動程序名>:\Program Files\Microsoft Enterprise Library January \bin文件夾如果還需要結合異常處理使用日志記錄則再添加對MicrosoftPracticesEnterpriseLibraryExceptionHandlingLoggingdll的引用

   在nfig或者nfig文件中添加必要的配置項為此可在根<configuration>元素下的<configSections>元素中添加如下內容
    
     <section name=exceptionHandling
type=MicrosoftPracticesEnterpriseLibraryExceptionHandling
ConfigurationExceptionHandlingSettingsMicrosoftPractices
EnterpriseLibraryExceptionHandling />     
    如果隨同異常處理一起使用日志記錄則還需要在<configSections>元素中添加以下設置
    
   <section name=loggingConfiguration
type=MicrosoftPracticesEnterpriseLibraryLoggingConfiguration
LoggingSettingsMicrosoftPracticesEnterpriseLibraryLogging />
    
    接下來直接在<configuration>元素下添加<exceptionHandling>元素在<exceptionHandling>內部可添加所有的異常處理策略以下代碼說明在<exceptionHandling>中指定了一個名為Global Policy的策略

    <exceptionHandling>
<exceptionPolicies>
<add name=Log Only Policy>
<exceptionTypes>
<add name=Exception type=SystemException mscorlib
Version= Culture=neutral PublicKeyToken=bace
postHandlingAction=ThrowNewException>
<exceptionHandlers>
<add logCategory=Default Category eventId= severity=Error
title=Exception Management Application Exception priority=
formatterType=MicrosoftPracticesEnterpriseLibrary
ExceptionHandlingTextExceptionFormatter
MicrosoftPracticesEnterpriseLibraryExceptionHandling
name=Logging Handler
type=MicrosoftPracticesEnterpriseLibraryExceptionHandling
LoggingLoggingExceptionHandler
MicrosoftPracticesEnterpriseLibrary
ExceptionHandlingLogging/>
</exceptionHandlers>
</add>
</exceptionTypes>
</add>
</exceptionPolicies>
</exceptionHandling>
    
    正如這些設置所指示的那樣有一個名為Log Only Policy的策略該策略能夠記錄異常使用<exceptionHandlers>節能夠設置以適當方式處理異常的自定義異常處理程序在這種情況下自定義處理程序實現LoggingExceptionHandler類postHandlingAction屬性用於根據策略設置異常處理之後的行為該屬性包括以下可能值NoneNotifyRethrow和ThrowNewException

   在代碼中導入異常處理塊的核心命名空間MicrosoftPracticesEnterpriseLibraryExceptionHandling

   開始使用上述命名空間中的類編寫代碼

  ExceptionPolicy對象

  只要使用異常處理塊就必須處理ExceptionPolicy類ExceptionPolicy類公開了靜態方法HandleException()利用該方法可使客戶端應用程序與異常處理塊交互此時將策略作為參數提供HandleException()方法使用類工廠來為相應的策略創建ExceptionPolicyImpl類型的對象ExceptionPolicyImpl對象具有一個ExceptionPolicyEntry對象集合在名為策略的配置文件中每種異常類型都對應一個對象對每一種異常類型ExceptionPolicyEntry對象都包含一個實現IExceptionHandler接口的對象集合當執行策略時對象集合能夠提供異常處理塊使用的序列每個實現IExceptionHandler接口的對象都與對應處理方法的類型相關聯

  異常處理方法是 NET類其封裝了異常處理邏輯並實現了定義在異常處理塊中的IExceptionHandler接口默認情況下異常處理塊包含以下三種異常處理程序

  封裝處理程序此異常處理程序使用一個異常封裝另一個異常
    取代處理程序此異常處理程序用一個異常取代另一個異常
    日志記錄處理程序此異常處理程序對異常信息進行格式化處理例如消息和堆棧跟蹤然後日志記錄處理方法將這些信息記錄到日志塊以作日後查證

  既然已經了解了異常處理塊的基礎知識下面將重新講解業務邏輯層類的代碼以便理解異常處理塊的集成
    
   public IList<ProductCategory> GetProductCategories()
{
try
{
ProductCategoryDB category = new ProductCategoryDB();
return categoryGetProductCategories();
}
catch (Exception ex)
{
bool rethrow = ExceptionPolicyHandleException(ex Log Only Policy);
if (rethrow)
{
throw;
}
return null;
}
}
    
    在try塊中無論何時發生異常都將在catch塊中捕獲異常並在其中調用ExceptionPolicy對象的HandleException()方法以便記錄異常在記錄異常之後可查看HandleException()方法的返回值(根據配置文件中的postHandlingAction屬性)以便確定是否需要向調用者拋出異常

   小結

  本文介紹的數據訪問層實現中涉及集成重用塊開發人員使用這些塊能夠快速方便的實現數據訪問異常處理等很多重復性高的任務建議讀者在學習這些重用塊之後將其應用到自身的項目開發過程中從而提高開發效率
    下一篇文章講解Web站點部分的實現方法


From:http://tw.wingwit.com/Article/program/net/201311/12119.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.