ASP.NET 2.0数据教程之二:创建一个业务逻辑层
[2] ASP.NET 2.0数据教程之二:创建一个业务逻辑层
[3] ASP.NET 2.0数据教程之二:创建一个业务逻辑层
[4] ASP.NET 2.0数据教程之二:创建一个业务逻辑层
[5] ASP.NET 2.0数据教程之二:创建一个业务逻辑层
[6] ASP.NET 2.0数据教程之二:创建一个业务逻辑层
[7] ASP.NET 2.0数据教程之二:创建一个业务逻辑层
系列文章导航:
ASP.NET 2.0数据教程之四:使用ObjectDataSource展现数据
ASP.NET 2.0数据教程之六:编程设置ObjectDataSource的参数值
ASP.NET 2.0数据教程之七:使用DropDownList过滤的主/从报表
ASP.NET 2.0数据教程之八:使用两个DropDownList过滤的主/从报表
ASP.NET 2.0数据教程之十:使用 GridView 和DetailView实现的主/从报表
ASP.NET 2.0数据教程之十一:基于数据的自定义格式化
ASP.NET 2.0数据教程之十二:在GridView控件中使用TemplateField
第一步:创建BLL类
我们的BLL由4个类组成,每一个BLL类都对应DAL中的一个TableAdapter,它们都从各自的TableAdapter中得到读取、插入、修改以及删除等方法以应用合适的业务规则。
为了更加清晰的区分DAL和BLL的类,我们在App_Code文件夹中建立两个子文件夹,分别命名为DAL和BLL。你仅仅需要在解决方案浏览器(Solution Explorer)中右键点击App_Code文件夹,并选择新建文件夹(New Folder),就可以创建新的子文件夹了。建好了这两个文件夹之后,把第一节中所创建的类型化数据集(Typed DataSet)移到DAL文件夹中。
然后,在BLL文件夹中创建4个类文件。同样,你仅仅需要在解决方案浏览器(Solution Explorer)中右键点击BLL文件夹,并选择新建项目(New Item),然后在弹出的对话框中选择类模板(Class template)就可以创建新的类文件了。将这四个文件分别命名为ProductsBLL、CategoriesBLL、SuppliersBLL以及EmployeesBLL。

图二:在BLL文件夹中添加4个新的类
接下来,让我们来给这些新建的类加上一些方法,简单的将第一节中的TableAdapter中的那些方法包装起来就行了。现在,这些方法将只能直接使用DAL中的那些方法,我们等会再来给他们加上一些业务逻辑。
注意:如果你使用的是Visual Studio 标准版或以上版本(也就是说,你不是用的Visual Web Developer),那么你还可以使用Class Designer来可视化的设计你的类。你可以在Class Designer Blog上得到关于Visual Studio的这项新功能的详细信息。
在ProductsBLL类中,我们一共需要为其添加7个方法:
l GetProducts() – 返回所有的产品
l GetProductByProductID(productID) – 返回指定ProductID的产品
l GetProductsByCategoryID(categoryID) –返回指定分类的产品
l GetProductsBySupplier(supplierID) –返回指定供应商的产品
l AddProduct(productName, supplierID, categoryID, quantityPerUnit, unitPrice, unitsInStock, unitsOnOrder, reorderLevel, discontinued) – 向数据库中添加一条产品信息,并返回新添加的产品的ProductID
l UpdateProduct(productName, supplierID, categoryID, quantityPerUnit, unitPrice, unitsInStock, unitsOnOrder, reorderLevel, discontinued, productID) – 更新一个数据库中已经存在的产品,如果刚好更新了一条记录,则返回true,否则返回false
l DeleteProduct(productID) – 删除指定ProductID的产品
1
using System;2
using System.Data;3
using System.Configuration;4
using System.Web;5
using System.Web.Security;6
using System.Web.UI;7
using System.Web.UI.WebControls;8
using System.Web.UI.WebControls.WebParts;9
using System.Web.UI.HtmlControls;10
using NorthwindTableAdapters;11

12
[System.ComponentModel.DataObject]13
public class ProductsBLL14


{15
private ProductsTableAdapter _productsAdapter = null;16
protected ProductsTableAdapter Adapter17

{18

get
{19
if (_productsAdapter == null)20
_productsAdapter = new ProductsTableAdapter();21

22
return _productsAdapter; 23
}24
}25

26

27
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]28
public Northwind.ProductsDataTable GetProducts()29

{ 30
return Adapter.GetProducts();31
}32

33
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, false)]34
public Northwind.ProductsDataTable GetProductByProductID(int productID)35

{36
return Adapter.GetProductByProductID(productID);37
}38

39
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, false)]40
public Northwind.ProductsDataTable GetProductsByCategoryID(int categoryID)41

{42
return Adapter.GetProductsByCategoryID(categoryID);43
}44

45
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, false)]46
public Northwind.ProductsDataTable GetProductsBySupplierID(int supplierID)47

{48
return Adapter.GetProductsBySupplierID(supplierID);49
}50
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Insert, true)]51
public bool AddProduct(string productName, int? supplierID, int? categoryID, string quantityPerUnit, 52
decimal? unitPrice, short? unitsInStock, short? unitsOnOrder, short? reorderLevel, 53
bool discontinued)54

{55
// 新建一个ProductRow实例56
Northwind.ProductsDataTable products = new Northwind.ProductsDataTable();57
Northwind.ProductsRow product = products.NewProductsRow();58

59
product.ProductName = productName;60
if (supplierID == null) product.SetSupplierIDNull(); else product.SupplierID = supplierID.Value;61
if (categoryID == null) product.SetCategoryIDNull(); else product.CategoryID = categoryID.Value;62
if (quantityPerUnit == null) product.SetQuantityPerUnitNull(); else product.QuantityPerUnit = quantityPerUnit;63
if (unitPrice == null) product.SetUnitPriceNull(); else product.UnitPrice = unitPrice.Value;64
if (unitsInStock == null) product.SetUnitsInStockNull(); else product.UnitsInStock = unitsInStock.Value;65
if (unitsOnOrder == null) product.SetUnitsOnOrderNull(); else product.UnitsOnOrder = unitsOnOrder.Value;66
if (reorderLevel == null) product.SetReorderLevelNull(); else product.ReorderLevel = reorderLevel.Value;67
product.Discontinued = discontinued;68

69
// 添加新产品70
products.AddProductsRow(product);71
int rowsAffected = Adapter.Update(products);72

73
// 如果刚好新增了一条记录,则返回true,否则返回false74
return rowsAffected == 1;75
}76

77
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, true)]78
public bool UpdateProduct(string productName, int? supplierID, int? categoryID, string quantityPerUnit,79
decimal? unitPrice, short? unitsInStock, short? unitsOnOrder, short? reorderLevel,80
bool discontinued, int productID)81

{82
Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);83
if (products.Count == 0)84
// 没有找到匹配的记录,返回false85
return false;86

87
Northwind.ProductsRow product = products[0];88

89
product.ProductName = productName;90
if (supplierID == null) product.SetSupplierIDNull(); else product.SupplierID = supplierID.Value;91
if (categoryID == null) product.SetCategoryIDNull(); else product.CategoryID = categoryID.Value;92
if (quantityPerUnit == null) product.SetQuantityPerUnitNull(); else product.QuantityPerUnit = quantityPerUnit;93
if (unitPrice == null) product.SetUnitPriceNull(); else product.UnitPrice = unitPrice.Value;94
if (unitsInStock == null) product.SetUnitsInStockNull(); else product.UnitsInStock = unitsInStock.Value;95
if (unitsOnOrder == null) product.SetUnitsOnOrderNull(); else product.UnitsOnOrder = unitsOnOrder.Value;96
if (reorderLevel == null) product.SetReorderLevelNull(); else product.ReorderLevel = reorderLevel.Value;97
product.Discontinued = discontinued;98

99
// 更新产品记录100
int rowsAffected = Adapter.Update(product);101

102
// 如果刚好更新了一条记录,则返回true,否则返回false103
return rowsAffected == 1;104
}105

106
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Delete, true)]107
public bool DeleteProduct(int productID)108

{109
int rowsAffected = Adapter.Delete(productID);110

111
// 如果刚好删除了一条记录,则返回true,否则返回false112
return rowsAffected == 1;113
}114
}115

GetProducts、GetProductByProductID、GetProductsByCategoryID以及 GetProductBySuppliersID等方法都仅仅是简简单单的直接调用DAL中的方法来返回数据。不过在有的情况下,我们还可能需要给它们实现一些业务规则(比如说授权规则,不同的用户或不用角色应该可以看到不同的数据),现在我们简单的将它们做成这样就可以了。那么,对于这些方法来说,BLL仅仅是作为表示层与DAL之间的代理。
AddProduct和UpdateProduct这两个方法都使用参数中的那些产品信息去添加或是更新一条产品记录。由于Product表中有许多字段都允许空值(CategoryID、SupplierID、UnitPrice……等等),所以AddProduct和UpdateProduct中相应的参数就使用nullable types。Nullable types是.NET 2.0中新提供的一种用于标明一个值类型是否可以为空的技术。在C#中,你可以在一个允许为空的值类型后面加上一个问号(比如,int? x;)。关于Nullable Types的详细信息,你可以参考C# Programming Guide。
由于插入、修改和删除可能不会影响任何行,所以这三种方法均返回一个bool值用于表示操作是否成功。比如说,页面开发人员使用一个并不存在的ProductID去调用DeleteProduct,很显然,提交给数据库的DELETE语句将不会有任何作用,所以DeleteProduct会返回false。