PetShop4數據訪問層探祕

 namespace PetShop.DALFactory:

 

我們已經很清楚的知道:PetShop4中的數據訪問層採用的是典型的工廠模式設計,而實現工廠模式的項目就是DALFactory,該項目中只有一個封裝類(sealed):DataAccess,封裝表明該類不能被繼承,原代碼中對類的描述如下:

/// <summary>

/// This class is implemented following the Abstract Factory pattern to create the DAL implementation

/// specified from the configuration file

/// </summary>

該類根據配置文件的設置,應用抽象工廠模式,來創建特定的DAL實例。

一開始,就讀取配置文件,以確定要使用的DAL實例:

// Look up the DAL implementation we should be using

private static readonly string path = ConfigurationManager.AppSettings["WebDAL"];

private static readonly string orderPath = ConfigurationManager.AppSettings["OrdersDAL"];

使用readonly來限定,以確定不會無意修改變量。

在配置文件中,我們查到:

<add key="WebDAL" value="PetShop.SQLServerDAL"/>

<add key="OrdersDAL" value="PetShop.SQLServerDAL"/>

接着,是創建各種對象的靜態(static)函數,這表明我們不能通過實例來引用這些靜態函數,只能通過類來調用。有意思的是,這些函數將根據path變量的值,動態確定要創建的實例對象,如在CreateCategory()函數中有:

public static PetShop.IDAL.ICategory CreateCategory() {

string className = path + ".Category";

return (PetShop.IDAL.ICategory)Assembly.Load(path).CreateInstance(className);

}

首先,確定要實例化的類名:className=”PetShop.SQLServerDAL.Category”,然後通過:Assembly.Load(path).CreateInstance(className)實現類的實例化,由於PetShop.SQLServerDAL.Category類實現了ICategory接口,因爲可以強制轉化爲PetShop.IDAL.ICategory類型。這樣就達到了“根據配置情況,自動實例化相關的子類,並以該類父類的形式返回該類的實例,對外實現了統一調用,統一返回值”的目標,實現了“工廠模式”的接口。

在DataAccess類的成員如下圖如示:

clip_image002

 

 

namespace PetShop.SQLServerDAL:

 

在該項目中,有如下圖所示的類:

clip_image004

這5個類分別對應數據庫MSPetShop4中的4個業務表:

clip_image006

及數據庫MSPetShop4Orders中的1個業務表:

clip_image008

前面提到了PetShop.SQLServerDAL.Category類,下面我們順着代碼研究一下該類。

Category類繼承自ICategory接口,因此,它必將實現ICategory接口(位於IDAL項目中)中的方法。

一開始聲明瞭三個常量,用於查詢數據的SQL語句:

private const string SQL_SELECT_CATEGORIES = "SELECT CategoryId, Name, Descn FROM Category";

private const string SQL_SELECT_CATEGORY = "SELECT CategoryId, Name, Descn FROM Category WHERE CategoryId = @CategoryId";

private const string PARM_CATEGORY_ID = "@CategoryId";

接着,實現ICateory中的方法:

/// Method to get all categories

public IList<CategoryInfo> GetCategories() {

IList<CategoryInfo> categories = new List<CategoryInfo>();

//Execute a query to read the categories

using(SqlDataReader rdr = SqlHelper.ExecuteReader(SqlHelper.ConnectionStringLocalTransaction, CommandType.Text, SQL_SELECT_CATEGORIES, null)) {

while (rdr.Read()) {

CategoryInfo cat = new CategoryInfo(rdr.GetString(0), rdr.GetString(1), rdr.GetString(2));

categories.Add(cat);

}

}

return categories;

}

GetCategories()方法是一個公開的方法,返回一個IList<CategoryInfo>的泛形值(詳見下文),在執行查詢的過程中,使用了using語句塊,把需要釋放資源的對象的聲明放到using塊的括號內,以保證系統在代碼退出該塊時釋放資源。如果正在使用消耗大量內存或其他組件也需要使用的系統資源時,這樣處理十分有用。using塊的括號內使用SqlHelper類(位於DBUnility項目中)中的ExecuteReader方法,返回一個SqlDataReader類型的對象。查詢的數據保存在此SqlDataReader對象中。接下來,調用對象的Read()方法,將數據行中的前三列數據一行一行的取出來,保存到CategoryInfo類型的對象中,用於返回。

上文中提到的IList<T>接口,是一個表示可按照索引單獨訪問的一組對象。<CategoryInfo>表示該組對象的類型是CategoryInfo型的。CategoryInfo是一個類,位於Model(Business entity used to model a product)項目中,對應於數據庫中的Category表,它是表在系統中的業務實體模型。對於PetShop4中的四個數據庫中的所有業務表,在Model項目中都有與之相對應的業務實體模型(類)。具體如下圖:

clip_image010

CatagoryInfo類中的成員如下圖所示:

clip_image012

包括兩個構造函數,三個屬性對應三個字段。從rdr中取出的數據行就是通過第二個構造函數保存到對象中去的。一行對應一個CatagoryInfo對象。

 

 

摘自:http://www.cnblogs.com/luckeryin/archive/2009/01/10/1373390.html

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