ASP.NET数据库访问系列教程01-概述篇 创建数据访问层(中)
ASP.NET數據庫訪問系列教程
本教程深入探討了基于ASP.NET 2.0技術的數據庫訪問方法和模式。這些介紹非常簡明,并且提供了一步步的指導和大量的截屏。
該系列教程包括:
- 概述篇
- 基礎報表
- 主/明細報表
- 自定義格式報表
- 編輯,插入和刪除數據
- 分頁和排序、自定義按鈕事件
- 使用DataList和Repeater控件顯示數據
- 使用DataList和Repeater進行數據篩選
- 通過DataList編輯和刪除數據
- 使用DataList和Repeater控件進行分頁和排序
- 自定義DataList和Repeater控件的按鈕事件
- 從ASP.NET頁面直接訪問數據庫
- 擴展GridView控件
- 操作二進制文件
- 數據緩存
- 基于數據庫的站點地圖
- 批量數據處理
- 高級數據庫訪問操作
#1 概述篇-創建數據訪問層(中)
本文檔是 Visual C# 教程該教程從頭開始使用 Typed DataSet(強類型 DataSet)創建數據訪問層 (DAL),以訪問數據庫中的信息。
步驟3 :向數據訪問層添加帶參數的方法
我們的 ProductsTableAdapter 類此時有且只有一個方法:GetProducts() ,它返回數據庫內的所有產品信息。盡管能夠處理所有產品是肯定有用的,不過有時候我們希望只檢索特定產品或屬于某個類別的所有產品的信息。要在我們的數據訪問層中添加這個功能,可以通過帶參數的方法添加到TableAdapter 來實現。
現在我們添加 GetProductsByCategoryID(categoryID) 方法。向 DAL 添加一個新方法,返回到 DataSet Designer ,右鍵單擊ProductsTableAdapter 區域,并選擇Add Query 。
圖14 :右鍵單擊TableAdapter 并選擇 Add Query
我們首先被問到是否希望使用 ad-hoc SQL 語句或創建或使用現有的存儲過程來訪問數據庫。再次選擇使用ad-hoc SQL 語句。接下來會詢問我們想使用的 SQL 查詢類型。由于我們希望返回屬于某一指定類別的所有產品信息,我們想編寫一個返回行的SELECT 語句。
圖15 :選擇創建返回行的SELECT 語句
下一步是定義用來訪問數據的 SQL 查詢。由于我們希望只返回屬于某一指定類別的那些產品信息,我使用的是GetProducts() 中的同一個 SELECT 語句,但是添加了下面的 WHERE 子句:WHERE CategoryID = @CategoryID 。@CategoryID 參數向TableAdapter 向導表明,我們正在創建的方法將要求一個對應類型的輸入參數(也就是說,一個可為Null 的整數)。
圖16 :查詢只返回指定類別中的 產品信息
在最后一個步驟,我們可以選擇要使用的數據訪問模式,并自定義所生成方法的名稱。將Fill 模式重命名為FillByCategoryID ,并使用 GetProductsByCategoryID 作為返回 DataTable 返回模式(GetX 方法)的名稱。
圖17 :為TableAdapter 方法選擇名稱
向導結束后,DataSet 設計器包含新的TableAdapter 方法。
圖18 :產品現在可按類別進行查詢
使用同樣的技術再添加 GetProductByProductID(productID) 方法
可以直接從 DataSet 設計器對這些帶參數的查詢進行檢驗。右鍵單擊TableAdapter 中的方法并選擇 Preview Data 。然后輸入用于參數的值并單擊Preview 。
圖19 :顯示出的屬于飲料類別的產品信息
通過 DAL 中的 GetProductsByCategoryID(categoryID) 方法,我們現在可以創建一個只顯示指定類別的那些產品的ASP.NET 頁面。下面舉例顯示CategoryID 為1 的飲料類別中的所有產品信息。
Beverages.aspx
2 Inherits="Beverages" %>
3
4 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
5 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6
7 <html xmlns="http://www.w3.org/1999/xhtml" >
8 <head runat="server">
9 <title>Untitled Page</title>
10 <link href="Styles.css" rel="stylesheet" type="text/css" />
11 </head>
12 <body>
13 <form id="form1" runat="server">
14 <div>
15 <h2>Beverages</h2>
16 <p>
17 <asp:GridView ID="GridView1" runat="server"
18 CssClass="DataWebControlStyle">
19 <HeaderStyle CssClass="HeaderStyle" />
20 <AlternatingRowStyle CssClass="AlternatingRowStyle" />
21 </asp:GridView>
22 </p>
23 </div>
24 </form>
25 </body>
26 </html>
Beverages.aspx.cs
1 using System;2 using System.Data;
3 using System.Configuration;
4 using System.Collections;
5 using System.Web;
6 using System.Web.Security;
7 using System.Web.UI;
8 using System.Web.UI.WebControls;
9 using System.Web.UI.WebControls.WebParts;
10 using System.Web.UI.HtmlControls;
11 using NorthwindTableAdapters;
12
13 public partial class Beverages : System.Web.UI.Page
14 {
15 protected void Page_Load(object sender, EventArgs e)
16 {
17 ProductsTableAdapter productsAdapter = new
18 ProductsTableAdapter();
19 GridView1.DataSource =
20 productsAdapter.GetProductsByCategoryID(1);
21 GridView1.DataBind();
22 }
23 }
圖20 :顯示出的飲料類別中的產品
步驟4 : 數據的添加、更新和刪除
添加、更新和刪除數據的常用模式有兩種。第一種模式,我稱之為數據庫直接模式,當涉及的方法被調用時,會向數據庫發送一個INSERT 、UPDATE 或DELETE 命令,該命令只對單個數據庫記錄進行操作。這些方法通常通過一系列的標量值(整數、字符串、布爾類型、DateTimes 等)來傳遞參數,這些值與要添加、更新或刪除的值相對應。例如,采用這種模式對Products 表進行操作,刪除方法將采用一個整數參數,指明要刪除的記錄的ProductID ,而添加法將對 ProductName 采用字符串,對 UnitPrice 采用十進制,對 UnitsOnStock 采用整數值等。
圖21 :每個添加、更新和刪除請求被立即送達數據庫
我把另一種模式稱為批量更新模式,就是在一次方法調用中更新整個DataSet 、DataTable 、或 DataRows 集合。通過這種模式,開發人員在 DataTable 中刪除、添加并修改 DataRow ,然后將那些 DataRow 或 DataTable 傳遞給一個更新方法。該方法隨后列舉傳入的DataRow ,確定它們是否要進行修改、添加或刪除(通過DataRow 的RowState 屬性 值),并為每條記錄發出適當的數據庫請求。
圖22 :調用更新方法時,所有更改都和數據庫保持同步
TableAdapter 默認采用的是批量更新模式,但也支持數據庫直接模式。由于創建我們的TableAdapter 時選擇了 Advanced Properties 中的“Generate Insert, Update, and Delete statements ”選項,所以 ProductsTableAdapter 包含一個實現批量更新模式的 Update() 方法。具體點說,TableAdapter 包含 Update() 方法,可以傳入一個強類型的 DataTable ,即 Typed DataSet ,或一個或多個 DataRow 傳遞。如果您在首次創建 TableAdapter 時選中了“GenerateDBDirectMethods ”復選框,數據庫直接模式也可以通過Insert() 、Update() 和Delete() 方法來實現。
這兩種數據修改模式都使用 TableAdapter 的 InsertCommand 、UpdateCommand 和DeleteCommand 屬性來向數據庫發布它們的INSERT 、UPDATE 和DELETE 命令。您可以通過單擊 DataSet Designer 中的 TableAdapter 并轉入 Properties 窗口來檢查和修改InsertCommand 、UpdateCommand 和DeleteCommand 屬性。(要確信您已經選擇了 TableAdapter 并確保 ProductsTableAdapter 對象是 Properties 窗口中下拉列表中的被選中的選項。)
圖23 :TableAdapter 具有的 InsertCommand 、UpdateCommand 和 DeleteCommand 屬性
要檢查或修改這些數據庫命令的任何屬性,單擊CommandText 子屬性即可彈出Query Builder 。
圖24 :在Query Builder 配置INSERT 、UPDATE 和DELETE 語句
下面的代碼示例說明了如何使用批量更新模式使所有沒有斷貨的、庫存小于等于25 件的產品的價格提高一倍:
2 new NorthwindTableAdapters.ProductsTableAdapter();
3
4 // For each product, double its price if it is not discontinued and
5 // there are 25 items in stock or less
6 Northwind.ProductsDataTable products = productsAdapter.GetProducts();
7 foreach (Northwind.ProductsRow product in products)
8 if (!product.Discontinued && product.UnitsInStock <= 25)
9 product.UnitPrice *= 2;
10
11 // Update the products
12 productsAdapter.Update(products);
下面的代碼表明如何使用數據庫直接模式通過編碼實現刪除、更新某個產品,然后添加某個新產品:
1 NorthwindTableAdapters.ProductsTableAdapter productsAdapter =
2 new NorthwindTableAdapters.ProductsTableAdapter();
3
4 // Delete the product with ProductID 3
5 productsAdapter.Delete(3);
6
7 // Update Chai (ProductID of 1), setting the UnitsOnOrder to 15
8 productsAdapter.Update("Chai", 1, 1, "10 boxes x 20 bags",
9 18.0m, 39, 15, 10, false, 1);
10
11 // Add a new product
12 productsAdapter.Insert("New Product", 1, 1,
13 "12 tins per carton", 14.95m, 15, 0, 10, false);
?
創建自定義Insert 、Update 和Delete 方法
由數據庫直接方法創建的 Insert() 、Update() 和Delete() 方法有點麻煩,尤其是對于那些有許多列的表。看前面的代碼示例,沒有IntelliSense 的幫助,Products 表的列與Update() 和 Insert() 方法的每個輸入參數的映射關系就很不明顯。有時候我們可能只想更新一個或兩個列,或者需要一個自定義Insert() 方法,該方法可能返回新添加記錄的IDENTITY (自動遞增)字段的值。
要創建這樣的自定義方法,返回到DataSet Designer 。右鍵單擊 TableAdapter 并選擇 Add Query ,返回 TableAdapter 向導。在第二個屏幕上,我們可以指明要創建的查詢類型。現在我們創建一個添加新產品并返回新加記錄的ProductID 的值的方法。因此,選擇創建一個 INSERT 查詢。
圖25 :創建一個向Products 表添加新行的方法
下一個屏幕上出現 InsertCommand 的 CommandText 。在查詢末尾添加SELECT SCOPE_IDENTITY() 語句,這樣將返回同一范圍內添加到IDENTITY 列的最后一個identity 值。(參見技術文檔 了解有關SCOPE_IDENTITY() 的更多信息以及您可能希望使用 SCOPE_IDENTITY() 代替 @@IDENTITY 的原因。)確保您在添加SELECT 語句之前用一個分號結束INSERT 語句。(Scope_identity:只返回插入到當前作用域中的值. @@identity?返回在當前會話中的任何表內所生成的最后一個標識值,不受限于特定的作用域.)
圖26 :增大返回SCOPE_IDENTITY() 值的查詢范圍
最后,將新方法命名為InsertProduct 。
圖27 :設置新方法的名稱為InsertProduct
當您返回到 DataSet 設計器時,您會發現ProductsTableAdapter 包含了新方法:InsertProduct 。如果對應 Products 表中的每個列,這個新方法沒有對應的參數,可能就是您忘記用分號來終止INSERT 語句。配置InsertProduct 方法并確保您使用了分號來終止INSERT 和 SELECT 語句。
默認狀態下,添加方法調用的是非查詢方法,意味著它們返回的是受影響的行數。不過,我們希望InsertProduct 方法返回查詢返回的值,而不是受影響的行數。為此,將InsertProduct 方法的 ExecuteMode 的屬性修改為Scalar 。
圖28 :將 ExecuteMode 屬性更改為Scalar
下面的代碼表明了運行中的這個新的InsertProduct 方法:
1 NorthwindTableAdapters.ProductsTableAdapter productsAdapter =2 new NorthwindTableAdapters.ProductsTableAdapter();
3
4 // Add a new product
5 int new_productID = Convert.ToInt32(productsAdapter.InsertProduct
6 ("New Product", 1, 1, "12 tins per carton", 14.95m, 10, 0, 10, false));
7
8 // On second thought, delete the product
9 productsAdapter.Delete(new_productID);
?
轉載于:https://www.cnblogs.com/MingDe/archive/2011/06/10/2077751.html
總結
以上是生活随笔為你收集整理的ASP.NET数据库访问系列教程01-概述篇 创建数据访问层(中)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bat批处理教程 24
- 下一篇: 带分页码的分页算法