日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
ASP.NET2.0數(shù)據(jù)教程:創(chuàng)建BLL類

在ASP.NET 2.0中,我們其實(shí)可以將業(yè)務(wù)邏輯層(Business Logic Layer,以下簡(jiǎn)稱BLL)看作是在數(shù)據(jù)訪問(wèn)層和表示層之間進(jìn)行數(shù)據(jù)交換的橋梁,在這個(gè)章節(jié)中,我們將討論一下如何將這些業(yè)務(wù)規(guī)則集成到一個(gè)BLL中。需要說(shuō)明的是,在一個(gè)實(shí)際的應(yīng)用程序中,BLL都是以類庫(kù)(Class Library)的形式來(lái)實(shí)現(xiàn)的,不過(guò)為了簡(jiǎn)化工程的結(jié)構(gòu),在本教程中我們將BLL實(shí)現(xiàn)為App_Code文件夾中的一系列的類。圖一向我們展示了表示層、BLL以及DAL三者之間的結(jié)構(gòu)關(guān)系。

創(chuàng)新互聯(lián)網(wǎng)站建設(shè)提供從項(xiàng)目策劃、軟件開發(fā),軟件安全維護(hù)、網(wǎng)站優(yōu)化(SEO)、網(wǎng)站分析、效果評(píng)估等整套的建站服務(wù),主營(yíng)業(yè)務(wù)為成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作,成都App制作以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。創(chuàng)新互聯(lián)深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

圖一:BLL將表示層與DAL隔開了,并且加入了業(yè)務(wù)規(guī)則

***步:創(chuàng)建BLL類

我們的BLL由4個(gè)類組成,每一個(gè)BLL類都對(duì)應(yīng)DAL中的一個(gè)TableAdapter,它們都從各自的TableAdapter中得到讀取、插入、修改以及刪除等方法以應(yīng)用合適的業(yè)務(wù)規(guī)則。

為了更加清晰的區(qū)分DAL和BLL的類,我們?cè)贏pp_Code文件夾中建立兩個(gè)子文件夾,分別命名為DAL和BLL。你僅僅需要在解決方案瀏覽器(Solution Explorer)中右鍵點(diǎn)擊App_Code文件夾,并選擇新建文件夾(New Folder),就可以創(chuàng)建新的子文件夾了。建好了這兩個(gè)文件夾之后,把***節(jié)中所創(chuàng)建的類型化數(shù)據(jù)集(Typed DataSet)移到DAL文件夾中。

然后,在BLL文件夾中創(chuàng)建4個(gè)類文件。同樣,你僅僅需要在解決方案瀏覽器(Solution Explorer)中右鍵點(diǎn)擊BLL文件夾,并選擇新建項(xiàng)目(New Item),然后在彈出的對(duì)話框中選擇類模板(Class template)就可以創(chuàng)建新的類文件了。將這四個(gè)文件分別命名為ProductsBLL、CategoriesBLL、SuppliersBLL以及EmployeesBLL。

圖二:在BLL文件夾中添加4個(gè)新的類

接下來(lái),讓我們來(lái)給這些新建的類加上一些方法,簡(jiǎn)單的將***節(jié)中的TableAdapter中的那些方法包裝起來(lái)就行了?,F(xiàn)在,這些方法將只能直接使用DAL中的那些方法,我們等會(huì)再來(lái)給他們加上一些業(yè)務(wù)邏輯。

注意:如果你使用的是Visual Studio 標(biāo)準(zhǔn)版或以上版本(也就是說(shuō),你不是用的Visual Web Developer),那么你還可以使用Class Designer來(lái)可視化的設(shè)計(jì)你的類。你可以在Class Designer Blog上得到關(guān)于Visual Studio的這項(xiàng)新功能的詳細(xì)信息。

在ProductsBLL類中,我們一共需要為其添加7個(gè)方法:

l         GetProducts() – 返回所有的產(chǎn)品

l         GetProductByProductID(productID) – 返回指定ProductID的產(chǎn)品

l         GetProductsByCategoryID(categoryID) –返回指定分類的產(chǎn)品

l         GetProductsBySupplier(supplierID) –返回指定供應(yīng)商的產(chǎn)品

l         AddProduct(productName, supplierID, categoryID, quantityPerUnit, unitPrice, unitsInStock, unitsOnOrder, reorderLevel, discontinued) – 向數(shù)據(jù)庫(kù)中添加一條產(chǎn)品信息,并返回新添加的產(chǎn)品的ProductID

l         UpdateProduct(productName, supplierID, categoryID, quantityPerUnit, unitPrice, unitsInStock, unitsOnOrder, reorderLevel, discontinued, productID) – 更新一個(gè)數(shù)據(jù)庫(kù)中已經(jīng)存在的產(chǎn)品,如果剛好更新了一條記錄,則返回true,否則返回false

l         DeleteProduct(productID) – 刪除指定ProductID的產(chǎn)品

 
 
 
 
  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. [System.ComponentModel.DataObject]
  12. public class ProductsBLL
  13. {
  14.     private ProductsTableAdapter _productsAdapter = null;
  15.     protected ProductsTableAdapter Adapter
  16.     {
  17.         get {
  18.             if (_productsAdapter == null)
  19.                 _productsAdapter = new ProductsTableAdapter();
  20.             return _productsAdapter; 
  21.         }
  22.     }
  23. [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]
  24.     public Northwind.ProductsDataTable GetProducts()
  25.     {        
  26.         return Adapter.GetProducts();
  27.     }
  28.     [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, false)]
  29.     public Northwind.ProductsDataTable GetProductByProductID(int productID)
  30.     {
  31.         return Adapter.GetProductByProductID(productID);
  32.     }
  33. [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, false)]
  34.    public Northwind.ProductsDataTable GetProductsByCategoryID(int categoryID)
  35.     {
  36.         return Adapter.GetProductsByCategoryID(categoryID);
  37.    }
  38. [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, false)]
  39.     public Northwind.ProductsDataTable GetProductsBySupplierID(int supplierID)
  40.     {
  41.         return Adapter.GetProductsBySupplierID(supplierID);
  42.     }
  43.     [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Insert, true)]
  44.     public bool AddProduct(string productName, int? supplierID, int? categoryID, string quantityPerUnit, 
  45.                           decimal? unitPrice, short? unitsInStock, short? unitsOnOrder, short? reorderLevel, 
  46.                           bool discontinued)
  47.     {
  48.         // 新建一個(gè)ProductRow實(shí)例
  49.         Northwind.ProductsDataTable products = new Northwind.ProductsDataTable();
  50.         Northwind.ProductsRow product = products.NewProductsRow();
  51.         product.ProductName = productName;
  52.         if (supplierID == null) product.SetSupplierIDNull(); else product.SupplierID = supplierID.Value;
  53.         if (categoryID == null) product.SetCategoryIDNull(); else product.CategoryID = categoryID.Value;
  54.         if (quantityPerUnit == null) product.SetQuantityPerUnitNull(); else product.QuantityPerUnit = quantityPerUnit;
  55.         if (unitPrice == null) product.SetUnitPriceNull(); else product.UnitPrice = unitPrice.Value;
  56.         if (unitsInStock == null) product.SetUnitsInStockNull(); else product.UnitsInStock = unitsInStock.Value;
  57.         if (unitsOnOrder == null) product.SetUnitsOnOrderNull(); else product.UnitsOnOrder = unitsOnOrder.Value;
  58.         if (reorderLevel == null) product.SetReorderLevelNull(); else product.ReorderLevel = reorderLevel.Value;
  59.         product.Discontinued = discontinued;
  60.         // 添加新產(chǎn)品
  61.         products.AddProductsRow(product);
  62.         int rowsAffected = Adapter.Update(products);
  63.         // 如果剛好新增了一條記錄,則返回true,否則返回false
  64.         return rowsAffected == 1;
  65.     }
  66.     [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, true)]
  67.     public bool UpdateProduct(string productName, int? supplierID, int? categoryID, string quantityPerUnit,
  68.                               decimal? unitPrice, short? unitsInStock, short? unitsOnOrder, short? reorderLevel,
  69.                               bool discontinued, int productID)
  70.     {
  71.         Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
  72.         if (products.Count == 0)
  73.             // 沒(méi)有找到匹配的記錄,返回false
  74.             return false;
  75.         Northwind.ProductsRow product = products[0];
  76.         product.ProductName = productName;
  77.         if (supplierID == null) product.SetSupplierIDNull(); else product.SupplierID = supplierID.Value;
  78.         if (categoryID == null) product.SetCategoryIDNull(); else product.CategoryID = categoryID.Value;
  79.         if (quantityPerUnit == null) product.SetQuantityPerUnitNull(); else product.QuantityPerUnit = quantityPerUnit;
  80.         if (unitPrice == null) product.SetUnitPriceNull(); else product.UnitPrice = unitPrice.Value;
  81.         if (unitsInStock == null) product.SetUnitsInStockNull(); else product.UnitsInStock = unitsInStock.Value;
  82.         if (unitsOnOrder == null) product.SetUnitsOnOrderNull(); else product.UnitsOnOrder = unitsOnOrder.Value;
  83.         if (reorderLevel == null) product.SetReorderLevelNull(); else product.ReorderLevel = reorderLevel.Value;
  84.         product.Discontinued = discontinued;
  85.         // 更新產(chǎn)品記錄
  86.         int rowsAffected = Adapter.Update(product);
  87.         // 如果剛好更新了一條記錄,則返回true,否則返回false
  88.        return rowsAffected == 1;
  89.     }
  90.     [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Delete, true)]
  91.     public bool DeleteProduct(int productID)
  92.     {
  93.         int rowsAffected = Adapter.Delete(productID);
  94.         // 如果剛好刪除了一條記錄,則返回true,否則返回false
  95.         return rowsAffected == 1;
  96.     }
  97. }

GetProducts、GetProductByProductID、GetProductsByCategoryID以及 GetProductBySuppliersID等方法都僅僅是簡(jiǎn)簡(jiǎn)單單的直接調(diào)用DAL中的方法來(lái)返回?cái)?shù)據(jù)。不過(guò)在有的情況下,我們還可能需要給它們實(shí)現(xiàn)一些業(yè)務(wù)規(guī)則(比如說(shuō)授權(quán)規(guī)則,不同的用戶或不用角色應(yīng)該可以看到不同的數(shù)據(jù)),現(xiàn)在我們簡(jiǎn)單的將它們做成這樣就可以了。那么,對(duì)于這些方法來(lái)說(shuō),BLL僅僅是作為表示層與DAL之間的代理。

AddProduct和UpdateProduct這兩個(gè)方法都使用參數(shù)中的那些產(chǎn)品信息去添加或是更新一條產(chǎn)品記錄。由于Product表中有許多字段都允許空值(CategoryID、SupplierID、UnitPrice……等等),所以AddProduct和UpdateProduct中相應(yīng)的參數(shù)就使用nullable types。Nullable types是.NET 2.0中新提供的一種用于標(biāo)明一個(gè)值類型是否可以為空的技術(shù)。在C#中,你可以在一個(gè)允許為空的值類型后面加上一個(gè)問(wèn)號(hào)(比如,int? x;)。關(guān)于Nullable Types的詳細(xì)信息,你可以參考C# Programming Guide。

由于插入、修改和刪除可能不會(huì)影響任何行,所以這三種方法均返回一個(gè)bool值用于表示操作是否成功。比如說(shuō),頁(yè)面開發(fā)人員使用一個(gè)并不存在的ProductID去調(diào)用DeleteProduct,很顯然,提交給數(shù)據(jù)庫(kù)的DELETE語(yǔ)句將不會(huì)有任何作用,所以DeleteProduct會(huì)返回false。

注意:當(dāng)我們?cè)谔砑踊蚋乱粋€(gè)產(chǎn)品的詳細(xì)信息時(shí),都是接受由產(chǎn)品信息組成的一個(gè)標(biāo)量列表,而不是直接接受一個(gè)ProductsRow實(shí)例。因?yàn)镻roductsRow是繼承于ADO.NET的DataRow,而DataRow沒(méi)有默認(rèn)的無(wú)參構(gòu)造函數(shù),為了創(chuàng)建一個(gè)ProductsRow的實(shí)例,我們必須先創(chuàng)建一個(gè)ProductsDataTable的實(shí)例,然后調(diào)用它的NewProductRow方法(就像我們?cè)贏ddProduct方法中所做的那樣)。不過(guò),當(dāng)我在使用ObjectDataSource來(lái)插入或更新時(shí),這樣做的缺點(diǎn)就會(huì)暴露出來(lái)了。簡(jiǎn)單的講,ObjectDataSource會(huì)試圖為輸入的參數(shù)創(chuàng)建一個(gè)實(shí)例,如果BLL方法希望得到一個(gè)ProductsRow,那么ObjectDataSource就將會(huì)試圖去創(chuàng)建一個(gè),不過(guò)很顯然,這樣的操作一定會(huì)失敗,因?yàn)闆](méi)有一個(gè)默認(rèn)的無(wú)參構(gòu)造函數(shù)。這個(gè)問(wèn)題的詳細(xì)信息,可以在ASP.NET論壇的以下兩個(gè)帖子中找到: Updating ObjectDataSources with Strongly-Typed DataSets、Problem With ObjectDataSource and Strongly-Typed DataSet。

之后,在AddProduct和UpdateProduct中,我們創(chuàng)建了一個(gè)ProductsRow實(shí)例,并將傳入的參數(shù)賦值給它。當(dāng)給一個(gè)DataRow的DataColumns賦值時(shí),各種字段級(jí)的有效性驗(yàn)證都有可能會(huì)被觸發(fā)。因此,我們應(yīng)該手工的驗(yàn)證一下傳入的參數(shù)以保證傳遞給BLL方法的數(shù)據(jù)是有效的。不幸的是,Visual Studio生成的強(qiáng)類型數(shù)據(jù)集(strongly-typed DataRow)并沒(méi)有使用nullable values。要表明DataRow中的一個(gè)DataColumn可以接受空值,我們就必須得使用SetColumnNameNull方法。

在UpdateProduct中,我們先使用GetProductByProductID(productID)方法將需要更新的產(chǎn)品信息讀取出來(lái)。這樣做好像沒(méi)有什么必要,不過(guò)我們將在之后的關(guān)于并發(fā)優(yōu)化(Optimistic concurrency)的課程中證明這個(gè)額外的操作是有它的作用的。并發(fā)優(yōu)化是一種保證兩個(gè)用戶同時(shí)操作一個(gè)數(shù)據(jù)而不會(huì)發(fā)生沖突的技術(shù)。獲取整條記錄同時(shí)也可以使創(chuàng)建一個(gè)僅更新DataRow的一部分列的方法更加容易,我們可以在SuppliersBLL類中找到這樣的例子。

***,注意我們?cè)赑roductsBLL類上面加上了DataObject 標(biāo)簽(就是在類聲明語(yǔ)句的上面的[System.ComponentModel.DataObject]),各方法上面還有DataObjectMethodAttribute 標(biāo)簽。DataObject標(biāo)簽把這個(gè)類標(biāo)記為可以綁定到一個(gè)ObjectDataSource控件,而DataObjectMethodAttribute則說(shuō)明了這個(gè)方法的目的。我們將在后面的教程中看到,ASP.NET 2.0的ObjectDataSource使從一個(gè)類中訪問(wèn)數(shù)據(jù)更加容易。為了ObjectDataSource向?qū)軌驅(qū)ΜF(xiàn)有的類進(jìn)行合適的篩選,在類列表中默認(rèn)僅顯示標(biāo)記為DataObject的類。當(dāng)然,其實(shí)ProductsBLL類就算沒(méi)有這個(gè)標(biāo)簽也可以工作,但是加上它可以使我們?cè)贠bjectDataSource向?qū)е械牟僮鞲虞p松和心情愉快。

添加其他的類

完成了ProductsBLL類之后,我們還要添加一些為categories、suppliers和employees服務(wù)的類。讓我們花點(diǎn)時(shí)間來(lái)創(chuàng)建下面的類,根據(jù)上面的例子來(lái)做就是了:

·         CategoriesBLL.cs

o        GetCategories()

o        GetCategoryByCategoryID(categoryID)

·         SuppliersBLL.cs

o        GetSuppliers()

o        GetSupplierBySupplierID(supplierID)

o        GetSuppliersByCountry(country)

o        UpdateSupplierAddress(supplierID, address, city, country)

·         EmployeesBLL.cs

o        GetEmployees()

o        GetEmployeeByEmployeeID(employeeID)

o        GetEmployeesByManager(managerID)

SuppliersBLL類中的UpdateSupplierAddress方法是一個(gè)值得注意的東西。這個(gè)方法提供了一個(gè)僅僅更新供應(yīng)商地址信息的接口。它首先根據(jù)指定的SupplierID讀出一個(gè)SupplierDataRow(使用GetSupplierBySupplierID方法),設(shè)置其關(guān)于地址的所有屬性,然后調(diào)用SupplierDataTable的Update方法。UpdateSupplierAddress方法的代碼如下所示:

 
 
 
 
  1. [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, true)]
  2. public bool UpdateSupplierAddress(int supplierID, string address, string city, string country)
  3. {
  4.     Northwind.SuppliersDataTable suppliers = Adapter.GetSupplierBySupplierID(supplierID);
  5.     if (suppliers.Count == 0)
  6.         // 沒(méi)有找到匹配的項(xiàng),返回false
  7.         return false;
  8.     else
  9.     {
  10.         Northwind.SuppliersRow supplier = suppliers[0];
  11.         if (address == null) supplier.SetAddressNull(); else supplier.Address = address;
  12.         if (city == null) supplier.SetCityNull(); else supplier.City = city;
  13.         if (country == null) supplier.SetCountryNull(); else supplier.Country = country;
  14.         // 更新供應(yīng)商的關(guān)于地址的信息
  15.         int rowsAffected = Adapter.Update(supplier);
  16.         // 如果剛好更新了一條記錄,則返回true,否則返回false
  17.         return rowsAffected == 1;
  18.     }
  19. }

分享標(biāo)題:ASP.NET2.0數(shù)據(jù)教程:創(chuàng)建BLL類
標(biāo)題URL:http://www.5511xx.com/article/dhsicgd.html