创建业务逻辑层导言本教程的第一节所描述的数据访问层(DataAccessLayer,以下简称为DAL)已经清晰地将表示逻辑与数据访问逻辑区分开了。不过,即使DAL将数据访问的细节从表示层中分离出来了,可它却不能处理任何的业务规则。比如说,我们可能不希望产品表中那些被标记为“停用”的产品的“分类编号”或“供应商编号”被更新;我们还可能需要应用一些资历规则,比如说我们都不希望被比自己的资历还要浅的人管理。另外一个比较常见的情况就是授权,比如说只有那些具有特殊权限的用户可以删除产品或是更改单价。我们其实可以将业务逻辑层(BusinessLogicLayer,以下简称BLL)看作是在数据访问层和表示层之间进行数据交换的桥梁,在这个章节中,我们将讨论一下如何将这些业务规则集成到一个BLL中。需要说明的是,在一个实际的应用程序中,BLL都是以类库(ClassLibrary)的形式来实现的,不过为了简化工程的结构,在本教程中我们将BLL实现为App_Code文件夹中的一系列的类。图一向我们展示了表示层、BLL以及DAL三者之间的结构关系。图一:BLL将表示层与DAL隔开了,并且加入了业务规则第一步:创建BLL类我们的BLL由4个类组成,每一个BLL类都对应DAL中的一个TableAdapter,它们都从各自的TableAdapter中得到读取、插入、修改以及删除等方法以应用合适的业务规则。为了更加清晰的区分DAL和BLL的类,我们在App_Code文件夹中建立两个子文件夹,分别命名为DAL和BLL。你仅仅需要在解决方案浏览器(SolutionExplorer)中右键点击App_Code文件夹,并选择新建文件夹(NewFolder),就可以创建新的子文件夹了。建好了这两个文件夹之后,把第一节中所创建的类型化数据集(TypedDataSet)移到DAL文件夹中。然后,在BLL文件夹中创建4个类文件。同样,你仅仅需要在解决方案浏览器(SolutionExplorer)中右键点击BLL文件夹,并选择新建项目(NewItem),然后在弹出的对话框中选择类模板(Classtemplate)就可以创建新的类文件了。将这四个文件分别命名为ProductsBLL、CategoriesBLL、SuppliersBLL以及EmployeesBLL。图二:在BLL文件夹中添加4个新的类接下来,让我们来给这些新建的类加上一些方法,简单的将第一节中的TableAdapter中的那些方法包装起来就行了。现在,这些方法将只能直接使用DAL中的那些方法,我们等会再来给他们加上一些业务逻辑。注意:如果你使用的是VisualStudio标准版或以上版本(也就是说,你不是用的VisualWebDeveloper),那么你还可以使用在ProductsBLL类中,我们一共需要为其添加7个方法:lGetProducts()–返回所有的产品lGetProductByProductID(productID)–返回指定ProductID的产品lGetProductsByCategoryID(categoryID)–返回指定分类的产品lGetProductsBySupplier(supplierID)–返回指定供应商的产品lAddProduct(productName,supplierID,categoryID,quantityPerUnit,unitPrice,unitsInStock,unitsOnOrder,reorderLevel,discontinued)–向数据库中添加一条产品信息,并返回新添加的产品的ProductIDlUpdateProduct(productName,supplierID,categoryID,quantityPerUnit,unitPrice,unitsInStock,unitsOnOrder,reorderLevel,discontinued,productID)–更新一个数据库中已经存在的产品,如果刚好更新了一条记录,则返回true,否则返回falselDeleteProduct(productID)–删除指定ProductID的产品1usingSystem;2usingSystem.Data;3usingSystem.Configuration;4usingSystem.Web;5usingSystem.Web.Security;6usingSystem.Web.UI;7usingSystem.Web.UI.WebControls;8usingSystem.Web.UI.WebControls.WebParts;9usingSystem.Web.UI.HtmlControls;10usingNorthwindTableAdapters;1112[System.ComponentModel.DataObject]13publicclassProductsBLL14{15privateProductsTableAdapter_productsAdapter=null;16protectedProductsTableAdapterAdapter17{18get{19if(_productsAdapter==null)20_productsAdapter=newProductsTableAdapter();2122return_productsAdapter;23}24}252627[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select,true)]28publicNorthwind.ProductsDataTableGetProducts()29{30returnAdapter.GetProducts();31}3233[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select,false)]34publicNorthwind.ProductsDataTableGetProductByProductID(intproductID)35{36returnAdapter.GetProductByProductID(productID);37}3839[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select,false)]40publicNorthwind.ProductsDataTableGetProductsByCategoryID(intcategoryID)41{42returnAdapter.GetProductsByCategoryID(categoryID);43}4445[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select,false)]46publicNorthwind.ProductsDataTableGetProductsBySupplierID(intsupplierID)47{48returnAdapter.GetProductsBySupplierID(supplierID);49}50[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Insert,true)]51publicboolAddProduct(stringproductName,int?supplierID,int?categoryID,stringquantityPerUnit,52decimal?unitPrice,short?unitsInStock,short?unitsOnOrder,short?reorderLevel,53booldiscontinued)54{55//新建一个ProductRow实例56Northwind.ProductsDataTableproducts=newNorthwind.ProductsDataTable();57Northwind.ProductsRowproduct=products.NewProductsRow();5859product.ProductName=productName;60if(supplierID==null)product.SetSupplierIDNull();elseproduct.SupplierID=supplierID.Value;61if(categoryID==null)product.SetCategoryIDNull();elseproduct.CategoryID=categoryID.Value;62if(quantityPerUnit==null)product.SetQuantityPerUnitNull();elseproduct.QuantityPerUnit=quantityPerUnit;63if(unitPrice==null)product.SetUnitPriceNull();elseproduct.UnitPrice=unitPrice.Value;64if(unitsInStock==null)product.SetUnitsInStockNull();elseproduct.UnitsInStock=unitsInStock.Value;65if(unitsOnOrder==null)product.SetUnitsOnOrderNull();elseproduct.UnitsOnOrder=unitsOnOrder.Value;66if(reorderLevel==null)product.SetReorderLevelNull();elseproduct.ReorderLevel=reorderLevel.Value;67product.Discontinued=discontinued;6869//添加新产品70products.AddProductsRow(product);71introwsAffected=Adapter.Update(products);7273//如果刚好新增了一条记录,则返回true,否则返回false74returnrowsAffected==1;75}7677[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update,true)]78publicboolUpdateProduct(stringproductName,int?supplierID,int?categoryID,stringquantityPerUnit,79decimal?unitPrice,short?unitsInStock,short?unitsOnOrder,short?reorderLevel,80booldiscontinued,intproductID)81{82Northwind.ProductsDataTableproducts=Adapter.GetProductByProductID(productID);83if(products.Count==0)84//没有找到匹配的记录,返回false85returnfalse;8687Northwind.ProductsRowproduct=produc