现在的位置: 首页 > 综合 > 正文

PetShop4数据访问层探秘

2013年08月17日 ⁄ 综合 ⁄ 共 2647字 ⁄ 字号 评论关闭

namespace PetShop.DALFactory:

我们已经很清楚的知道:PetShop4中的数据访问层采用的是典型的工厂模式设计,而实现工厂模式的项目就是DALFactory,该项目中只有一个封装类(sealed):DataAccess,封装表明该类不能被继承,原代码中对类的描述如下:

///

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

/// specified from the configuration file

///

该类根据配置文件的设置,应用抽象工厂模式,来创建特定的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来限定,以确定不会无意修改变量。

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

接着,是创建各种对象的静态(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 GetCategories() {

IList categories = new List();

//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的泛形值(详见下文),在执行查询的过程中,使用了using语句块,把需要释放资源的对象的声明放到using块的括号内,以保证系统在代码退出该块时释放资源。如果正在使用消耗大量内存或其他组件也需要使用的系统资源时,这样处理十分有用。using块的括号内使用SqlHelper类(位于DBUnility项目中)中的ExecuteReader方法,返回一个SqlDataReader类型的对象。查询的数据保存在此SqlDataReader对象中。接下来,调用对象的Read()方法,将数据行中的前三列数据一行一行的取出来,保存到CategoryInfo类型的对象中,用于返回。

上文中提到的IList接口,是一个表示可按照索引单独访问的一组对象。表示该组对象的类型是CategoryInfo型的。CategoryInfo是一个类,位于Model(Business entity used to model a product)项目中,对应于数据库中的Category表,它是表在系统中的业务实体模型。对于PetShop4中的四个数据库中的所有业务表,在Model项目中都有与之相对应的业务实体模型(类)。具体如下图:

clip_image010

CatagoryInfo类中的成员如下图所示:

clip_image012

包括两个构造函数,三个属性对应三个字段。从rdr中取出的数据行就是通过第二个构造函数保存到对象中去的。一行对应一个CatagoryInfo对象。

抱歉!评论已关闭.