ASP.NET2.0資料操作之建立資料訪問層(4)

來源:互聯網
上載者:User
第五步:完成資料訪問層

  注意,ProductsTableAdapters類從Products表中返回的 是CategoryID和SupplierID的值,但並不包括Categories表 的CategoryName欄位和Suppliers表的CompanyName欄位,儘管當 我們顯示產品資訊時,這些很可能是我們想要顯示的欄位。我們可以擴充TableAdapter的起始方 法GetProducts()來包含CategoryName和CompanyName欄位的值, 這方法進而會更新強型別的DataTable來包括這些新的欄位。

  但這會造成一個問題,因為TableAdapter的插入,更新,刪除資料的方法是基於這個起始方法的,幸運的是, 自動產生的插入,更新,刪除方法並不會受SELECT子句中的子查詢的影響。如果我們注意把 對Categories和Suppliers的查詢添加成子查詢,而不是用JOIN語 句的話,我們可以避免重做這些修改資料的方法。在ProductsTableAdapter中的GetProducts()方法上按右滑鼠,選擇“配置”,然後,把SELECT子句改成:

SQL
1            2            3            4            5            6            7            
SELECT     ProductID, ProductName, SupplierID, CategoryID,            QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued,            (SELECT CategoryName FROM Categories            WHERE Categories.CategoryID = Products.CategoryID) as CategoryName,            (SELECT CompanyName FROM Suppliers            WHERE Suppliers.SupplierID = Products.SupplierID) as SupplierName            FROM         Products            


圖29: 更新GetProducts()方法的SELECT語句

  在更新GetProducts()方法使用這個新查詢語句之後,對應的DataTable將包含2個新欄位,CategoryName和SupplierName。


圖30: Products DataTable多了2個新欄位

  花點時間把GetProductsByCategoryID(categoryID)方法中的SELECT 子句也更新一下。

  如果你使用JOIN句法更新GetProducts()中的SELECT語句的話 ,DataSet設計器不能使用DB直接模式自動產生插入,更新,以及刪除資料庫記錄的方法。你必須手工產生這 些方法,就象本教程早先時候我們對InsertProduct方法的做法一樣。此外,你必須手工提供 InsertCommand,UpdateCommand和DeleteCommand屬性值,假如你 想使用批更新模式的話。

  添加其他的TableAdapter

  到目前為止,我們只討論了針對單個資料表的單個TableAdapter。但是,Northwind資料庫裡含有我們需要在 我們的web應用中使用的幾個相關的表。一個強型別的DataSet可以包含多個相關的DataTable。因此,為了完 成我們的DAL,我們需要為這些我們將來要用到的資料表添加相應的DataTable。步驟如下,開啟 DataSet設計 器,在設計器上按右滑鼠,選擇“添加/TableAdapter”。這會產生一個新的DataTable和TableAdapter,然後我 們早先討論過的設定精靈會指引你完成配置。

  花上幾分鐘,建立對應於下列查詢的TableAdapter及其方法。注意,ProductsTableAdapter的查詢中包含了用以擷取每個產品的分類和供應商名字的子查詢。另外,如果你是隨著教程在做的話,你已經添加過ProductsTableAdapter類 的GetProducts()和GetProductsByCategoryID(categoryID)方法了。

  • ProductsTableAdapter

    • GetProducts:

      SELECT ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued , (SELECT CategoryName FROM
      Categories WHERE Categories.CategoryID =
      Products.ProductID) as CategoryName, (SELECT CompanyName
      FROM Suppliers WHERE Suppliers.SupplierID =
      Products.SupplierID) as SupplierName
      FROM Products

    • GetProductsByCategoryID:

      SELECT ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued , (SELECT CategoryName FROM
      Categories WHERE Categories.CategoryID =
      Products.ProductID) as CategoryName,
      (SELECT CompanyName FROM Suppliers WHERE
      Suppliers.SupplierID = Products.SupplierID) as SupplierName
      FROM Products
      WHERE CategoryID = @CategoryID

    • GetProductsBySupplierID

      SELECT ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued ,
      (SELECT CategoryName FROM Categories WHERE
      Categories.CategoryID = Products.ProductID)
      as CategoryName, (SELECT CompanyName FROM Suppliers
      WHERE Suppliers.SupplierID = Products.SupplierID)
      as SupplierName
      FROM Products
      WHERE SupplierID = @SupplierID

    • GetProductByProductID

      SELECT ProductID, ProductName, SupplierID, CategoryID,
      QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder,
      ReorderLevel, Discontinued , (SELECT CategoryName
      FROM Categories WHERE Categories.CategoryID =
      Products.ProductID) as CategoryName,
      (SELECT CompanyName FROM Suppliers
      WHERE Suppliers.SupplierID = Products.SupplierID)
      as SupplierName
      FROM Products
      WHERE ProductID = @ProductID

  • CategoriesTableAdapter
    • GetCategories

      SELECT CategoryID, CategoryName, Description
      FROM Categories

    • GetCategoryByCategoryID

      SELECT CategoryID, CategoryName, Description
      FROM Categories
      WHERE CategoryID = @CategoryID

  • SuppliersTableAdapter
    • GetSuppliers

      SELECT SupplierID, CompanyName, Address, City,
      Country, Phone
      FROM Suppliers

    • GetSuppliersByCountry

      SELECT SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM Suppliers
      WHERE Country = @Country

    • GetSupplierBySupplierID

      SELECT SupplierID, CompanyName, Address,
      City, Country, Phone
      FROM Suppliers
      WHERE SupplierID = @SupplierID

  • EmployeesTableAdapter
    • GetEmployees

      SELECT EmployeeID, LastName, FirstName,
      Title, HireDate, ReportsTo, Country
      FROM Employees

    • GetEmployeesByManager

      SELECT EmployeeID, LastName, FirstName,
      Title, HireDate, ReportsTo, Country
      FROM Employees
      WHERE ReportsTo = @ManagerID

    • GetEmployeeByEmployeeID

      SELECT ployeeID, LastName, FirstName,
      Title, HireDate, ReportsTo, Country
      FROM Employees
      WHERE EmployeeID = @EmployeeID


圖31:添加了四個TableAdapter後的DataSet設計器

  給DAL添加定製編碼

  添加到強型別DataSet中的TableAdapter和DataTable是在一個XML Schema定義文 件(Northwind.xsd)中定義的。你可以在方案總管裡在Northwind.xsd 檔案上按右滑鼠,選擇“查看編碼(View Code)”,開啟這個Schema檔案來查看其中內容。


圖32:Northwinds強型別DataSet的XML Schema定義檔案

  這個schema資訊在設計時編譯之後會被翻譯成C#或Visual Basic 編碼,或者如果有必要的話,會在運行時 翻譯,然後你就能在調試器裡單步遍曆執行。想查看這些自動產生的編碼的話,在類別檢視裡,展 開TableAdapter 類或者強型別的DataSet 類。如果在螢幕上看不到類別檢視的話,在“查看”(View)菜單裡選擇“ 類別檢視”,或者按鍵組合Ctrl+Shift+C。在類別檢視裡,你能看到強型別的DataSet類和TableAdapter類的屬性,方法和事件。想看某個特定的方法的編碼話,在類別檢視雙擊對應方法的名字或者在方法上按右滑鼠,選 擇“移至定義區(Go To Definition)”。


圖33:在類別檢視裡選擇“移至定義區(Go To Definition)”,查看自動產生的編碼

  雖然自動產生的編碼省時省力,但這樣的編碼往往是非常通用化的(generic),為滿足一個應用程式特有的需 求需要做些定製。但擴充自動產生的編碼的風險在於,如果產生這些編碼的工具決定該是重建這些編碼的 時候了,則會把你定製的編碼衝掉。使用.NET 2.0中的一個新的部分(partial)類的概念,很容易將一個類的 定義分寫在幾個檔案裡。這允許我們給自動產生的類添加我們自己的方法,屬性,和事件,而不用擔心Visual Studio會衝掉我們的定製編碼。

  為示範如何定製DAL起見,讓我們來給SuppliersRow 添加一個GetProducts()方法。這 個SuppliersRow類代表了Suppliers表的個別記錄,每個供應商(supplier)可以 提供0個到多個產品,所以GetProducts()將返回指定的供應商的這些產品。做法如 下,在App_Code檔案夾裡添加一個新的類檔案,將其命名為SuppliersRow.cs, 然後在其中添加下列編碼:

C#
1            2            3            4            5            6            7            8            9            10            11            12            13            14            15            16            17            
using System;            using System.Data;            using NorthwindTableAdapters;            public partial class            Northwind            {            public partial class            SuppliersRow            {            public Northwind.ProductsDataTable GetProducts()            {            ProductsTableAdapter productsAdapter =            new ProductsTableAdapter();            return            productsAdapter.GetProductsBySupplierID(this.SupplierID);            }            }            }            

  這個部分(partial)類指示編譯器在編譯Northwind.SuppliersRow類時,應該包含我們剛定義的這個GetProducts()方法。如果你編譯你的項目,然後返回類別檢視,你就會看到GetProducts()已被列為Northwind.SuppliersRow的一個方法。


圖34: GetProducts()方法成為Northwind.SuppliersRow類的一部 分

  GetProducts()方法現在就能用來枚舉一個指定供應商的產品列單,如下列編碼所示:

C#
1            2            3            4            5            6            7            8            9            10            11            12            13            14            15            16            17            18            19            
NorthwindTableAdapters.SuppliersTableAdapter            suppliersAdapter = new            NorthwindTableAdapters.SuppliersTableAdapter();            // Get all of the suppliers            Northwind.SuppliersDataTable suppliers =            suppliersAdapter.GetSuppliers();            // Enumerate the suppliers            foreach (Northwind.SuppliersRow supplier in suppliers)            {            Response.Write("Supplier: " +            supplier.CompanyName);            Response.Write("<ul>");            // List the products for this supplier            Northwind.ProductsDataTable products = supplier.GetProducts();            foreach (Northwind.ProductsRow product in products)            Response.Write("<li>" +            product.ProductName + "</li>");            Response.Write("</ul><p> </p>");            }            

  This data can also be displayed in any of ASP.NET's data Web controls. The following page uses a GridView control with two fields:資料也可以在任何一種ASP.NET的Web控制項中顯示。下面這個網頁 使用了含有2個欄位的GridView 控制項:

  • 一個BoundField用以顯示每個供應商的名字,
  • 另一個TemplateField,包含了一個BulletedList控制項,用來綁定針對每個供應商調用 的GetProducts()方法返回的結果

  我們將在以後的教程裡討論怎樣來顯示這樣的主/從(master-detail)報表。在這裡,這個例子的目的是用 來示範如何使用添加到Northwind.SuppliersRow類中的自訂的方法的。

SuppliersAndProducts.aspx

ASP.NET
1            2            3            4            5            6            7            8            9            10            11            12            13            14            15            16            17            18            19            20            21            22            23            24            25            26            27            28            29            30            31            32            33            34            35            36            37            38            39            40            41            
<%@ Page Language="C#"            AutoEventWireup="true" CodeFile="SuppliersAndProducts.aspx.cs"            Inherits="SuppliersAndProducts" %>            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0            Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">            <html xmlns="http://www.w3.org/1999/xhtml" >            <head runat="server">            <title>Untitled Page</title>            <link href="Styles.css"            rel="stylesheet"            type="text/css"            />            </head>            <body>            <form id="form1" runat="server">            <div>            <h1>            Suppliers and Their Products</h1>            <p>            <asp:GridView ID="GridView1" runat="server"            AutoGenerateColumns="False"            CssClass="DataWebControlStyle">            <HeaderStyle CssClass="HeaderStyle" />            <AlternatingRowStyle CssClass="AlternatingRowStyle" />            <Columns>            <asp:BoundField DataField="CompanyName"            HeaderText="Supplier" />            <asp:TemplateField HeaderText="Products">            <ItemTemplate>            <asp:BulletedList ID="BulletedList1"            runat="server" DataSource="<%#            ((Northwind.SuppliersRow)((System.Data.DataRowView)            Container.DataItem).Row).GetProducts() %>"            DataTextField="ProductName">            </asp:BulletedList>            </ItemTemplate>            </asp:TemplateField>            </Columns>            </asp:GridView>             </p>            </div>            </form>            </body>            </html>            

SuppliersAndProducts.aspx.cs

C#
1            2            3            4            5            6            7            8            9            10            11            12            13            14            15            16            17            18            19            20            21            22            
using System;            using System.Data;            using System.Configuration;            using System.Collections;            using System.Web;            using System.Web.Security;            using System.Web.UI;            using System.Web.UI.WebControls;            using System.Web.UI.WebControls.WebParts;            using System.Web.UI.HtmlControls;            using NorthwindTableAdapters;            public partial class            SuppliersAndProducts : System.Web.UI.Page            {            protected void            Page_Load(object sender, EventArgs e)            {            SuppliersTableAdapter suppliersAdapter = new            SuppliersTableAdapter();            GridView1.DataSource = suppliersAdapter.GetSuppliers();            GridView1.DataBind();            }            }            


圖 35: 供應商的公司名字列在左欄,他們的產品列在右欄

  總結

  構造web應用時,建立DAL應該是你最先做的步驟之一,應該在你開始建立表現層之前進行。使用Visual Studio的話,建立基於強型別DataSet的DAL是個可以不寫一行編碼,在10到15分鐘內就可完成的任務。以後的 教程將建立在這個DAL基礎之上。在下一個教程裡,我們將定義一堆商務規則,然後看一下如何在一個分開的 商務邏輯層裡實現這些規則。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.