Scott Mitchell 的 ASP.NET 2.0 數據教程之四十七 使用 SqlDataSource 控件檢索數據
使用 SqlDataSource 控件檢索數據
在前面的教程里,我們用 ObjectDataSource 控件充分的將表現層和數據訪問層( DAL )分開來。在這篇教程里我們看看怎樣在一個表現層和數據訪問層區分的不是很嚴格的簡單程序中使用 SqlDataSource 控件。
導言:
到目前為止,我們探討的教程是由表現層,業務邏輯層和數據訪問層構成的層次體系結構。數據訪問層和業務邏輯層分別在教程第一和第二章提到。在 Displaying Data With the ObjectDataSource 這篇教程里,我們探討了怎樣用 ASP.NET 2.0 的新控件 --ObjectDataSource 控件在表現層展示數據 。
本教程到目前為止用這種層次結構來處理數據。然而繞過這種體系結構,通過直接把數據查詢和業務邏輯放在 Web 頁面上,也可以達到直接在 ASP.NET 頁面上訪問,插入,更新,刪除數據庫數據的目的。對十分龐大或者復雜的應用程序而言,使用層次結構對程序的成功和可維護性是很重要的。然而對很簡單的程序來說,沒有必要使用層次體系結構。
ASP.NET 2.0 提供了 5 個內建的數據源控件, SqlDataSource 控件 , AccessDataSource 控件 , ObjectDataSource 控件 , XmlDataSource 控件 , 和 SiteMapDataSource 控件。 SqlDataSource 控件能直接從關系型數據庫中訪問和更新數據,包括 Microsoft SQL Server , Microsoft Access, Oracle, MySQL 等數據庫。在本章以及接下來的 3 章教程里面,我們將探討如何用 SqlDataSource 控件來查詢和篩選數據庫數據,包括插入,更新和刪除。
圖1:ASP.NET 2.0 的5個內建的數據源控件
比較ObjectDataSource控件和 SqlDataSource控件
從理論上說, ObjectDataSource 控件和 SqlDataSource 控件都是作為訪問數據的一種代理。就象在教程 Displaying Data With the ObjectDataSource 中討論的那樣,可以在 ObjectDataSource 控件中設置展示數據的數據類型,以及用來選擇,插入,更新和刪除數據所調用的方法。一旦完成了 ObjectDataSource 控件的設置, GridView, DetailsView, DataList 等數據 Web 控件便可以通過綁定 ObjectDataSource 控件調用其 Select(), Insert(), Delete(), 和 Update() methods 方法。
雖然 SqlDataSource 控件具有和 SqlDataSource 控件同樣的功能,但使用 SqlDataSource 控件時,我們必須提供詳細的數據庫連接字符串,以及用來執行選擇,更新,插入,刪除數據的 ad-hoc SQL 查詢
或存儲過程。當調用 SqlDataSource 控件的 Select(), Insert(), Update(), and Delete() 方法時, SqlDataSource 控件連接到數據庫,并傳遞適當的 SQL 查詢。下圖展示了這些方法如何連接數據庫,傳遞查詢和返回結果。
圖 2 SqlDataSource 控件充當訪問數據庫的代理
注意:在本章教程中我們主要關注如何從數據庫獲得數據,在后面的
Inserting, Updating, and Deleteing Data with the SqlDataSource
Control 教程中 , 我們將討論如何通過設置 SqlDataSource 控件以支持插入,更新和刪除數據。
SqlDataSource 控件和 AccessDataSource 控件
除了 SqlDataSource 控件外, ASP.NET 2.0 還包 AccessDataSource 控件。這兩種不同的控件使很多開發者誤以為 AccessDataSource 控件主要是被設計來與 Microsoft Access 數據庫打交道, SqlDataSource 控件主要是被設計來來與 Microsoft SQL Server 打交道。實際情況是, SqlDataSource 控件可以與幾乎所有 .NET 能訪問的關系型數據庫打交道。包括任何 OleDb , ODBC , compliant data stores, 比如: Microsoft SQL Server, Microsoft Access, Oracle, Informix, MySQL, and PostgreSQL 等。
SqlDataSource 控件和 AccessDataSource 控件的唯一區別在于 AccessDataSource 控件的數據庫連接信息只需要提供 Access 數據庫文件的訪問路徑。而 SqlDataSource 控件則需要提供完整的連接字符串。
第一步:創建 SqlDataSource 頁面
在我們探討用 SqlDataSource 控件直接操作數據庫數據之前,讓我們先花些時 間在我們的站點項目里添加這些本節里和下三節里需要的 ASP.NET 頁面。首先添加一個名為 SqlDataSource 的文件夾,在里面添加下列頁面,并配置為使用 Site.master 母板頁。
Default.aspx
Querying.aspx
ParameterizedQueries.aspx
InsertUpdateDelete.aspx
OptimisticConcurrency.aspx
圖 3 :為 SqlDataSource 相關教程添加頁面
類似在其它文件夾里, EditInsertDelete文件夾里的Default.aspx將列出這些教程章節。記得用戶控件提供這個功能。因此,從解決方案資源管理器中拖拽一個這個用戶控件到頁面的設計視圖,從而添加它到Default.aspx頁面
圖 4:將用戶控件添加到Default.aspx頁面
最后把這 4個頁面加入站點地圖中。打開Web.sitemap文件并且把下列代碼加在“Adding Custom Buttons to the DataList and Repeater”siteMapNode標記之后:
<siteMapNode url="~/SqlDataSource/Default.aspx"
title="Using the SqlDataSource Control"
description="Work directly with database data using the
SqlDataSource control.">
<siteMapNode url="~/SqlDataSource/Querying.aspx"
title="Retrieving Database Data"
description="Examines how to query data from a database that
can then be displayed through a data Web control."/>
<siteMapNodeurl="~/SqlDataSource/ParameterizedQueries.aspx"
title="Parameterized Queries"
description="Learn how to specify parameterized WHERE
clauses in the SqlDataSource's SELECT statement." />
<siteMapNode url="~/SqlDataSource/InsertUpdateDelete.aspx"
title="Inserting, Updating, and Deleting Database Data"
description="See how to configure the SqlDataSource to include INSERT, UPDATE, and DELETE statements." />
<siteMapNode url="~/SqlDataSource/OptimisticConcurrency.aspx"
title="Using Optimistic Concurrency"
description="Explore how to augment the SqlDataSource to
include support for optimistic concurrency." />
</siteMapNode>
圖 5:更新站點地圖使之包含新的頁面
第二步:添加并設置 SqlDataSource控件
在 SqlDataSource文件夾中打開Querying.aspx頁面,切換到設計試圖。從工具箱中拖一個SqlDataSource控件到 設計器中,設置其 ID 為 ProductsDataSource。和ObjectDataSource一樣,SqlDataSource不產生任何的聲明標記,所以現在在頁面上看起來就象一個灰色的方塊。點擊SqlDataSource控件的智能標簽,點“Configure Data Source”鏈接,進入數據源配置向導。
圖 6:在智能標簽里點擊“設置數據源”鏈接。
ObjectDataSource控件和 SqlDataSource控件的配置向導有些許不同,但最終目的都是相同的:詳細的說明了如何從數據庫獲取,插入,更新和刪除數據。ObjectDataSource控件明確指定了要訪問的數據庫,并提供了要使用的SQL查詢聲明或存儲過程的詳細情況
向導的第一步是選擇要訪問的數據庫,在下拉列表中包含了放在 App_Data 文件夾中的數據庫,以及添加到服務器資源管理器的數據連接節點中的數據庫。一旦我們將一個連接到App_Data文件夾中的NORTHWIND.MDF數據庫的連接字符串添加到項目的Web.config 文件中,這個連接字符串就會出現在下拉列表的選項。如下圖,選 中它,點“下一步”。
圖 7:從下拉列表里選擇NORTHWINDConnectionString
選擇數據庫后,向導轉入“如何從數據庫檢索數據”界面。有 2種方式:第一種指定自定義SQL語句或存儲過程,第二種是指定來自表或視圖的列。
注意:我們先探討使用“指定來自表或視圖的列”選項的實例,稍后再探討用“自定義 SQL語句或存儲過程”選項的實例。
圖 8是我們點擊“指定來自表或視圖的列”單選按鈕時的畫面,這里我們選擇Products表,返回ProductID, ProductName和UnitPrice 列。完成選擇后,在底部的方框內將顯示SQL語句: SELECT [ProductID], [ProductName], [UnitPrice] FROM [Products]
圖 8:從表Products返回數據。
完成上述設置后,點“下一步”按鈕,進入測試查詢界面,在這里可以測試上一步所設置的查詢的結果。點擊“測試查詢”按鈕,執行查詢。
圖 9:點擊“測試”,從SELECT 查詢檢索數據。
最后,點“完成”按鈕完成向導。
和 ObjectDataSource一樣,SqlDataSource的向導設置只是完成了對SqlDataSource控件屬性的賦值而已,即ConnectionString 屬性和SelectCommand 屬性。完成設置之后,我們的SqlDataSource控件代碼應該和下面的差不多:
<asp:SqlDataSource ID="ProductsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand="SELECT [ProductID], [ProductName], [UnitPrice] FROM [Products]">
</asp:SqlDataSource>
其中 ConnectionString屬性提供了怎樣連接數據庫的詳細信息,可以用完整的,硬編碼的連接字符串對其賦值,也可以用Web.config文件中的連接字符串來賦值。當用Web.config文件中的字符串時,語法為:<%$ expressionPrefix:expressionValue %>,特別地expressionPrefix就是“ConnectionStrings”,而expressionValue 則是Web.config文件<connectionStrings>部分中,連接字符串的名字。關于此語法的更多信息請參考: ASP.NET Expressions Overview
而 SelectCommand屬性是SQL查詢語句或存儲過程的詳細陳述。
第三步:添加數據 Web控件并綁定到SqlDataSource
一旦設置好 SqlDataSource后,就可以用GridView 或DetailsView等數據Web控件綁定它。在本篇教程中我們使用GridView,從工具箱拖一個GridView控件到頁面上,在智能標簽中的“選擇數據源”里選ProductsDataSource ,這樣就將GridView控件綁定到我們前面設置的SqlDataSource控件了。
圖 10:添加GridView控件并綁定到SqlDataSource
完成綁定后, Visual Studio 會自動為GridView從數據源控件返回的每一列添加一個BoundField 或CheckBoxField 。就本文來說既然SqlDataSource從數據庫返回三列:ProductID, ProductName, 和 UnitPrice ,那么Visual Studio就在自動在GridView中生成三列(three fields )。
花幾分鐘來設置 GridView的三個BoundFields:把ProductName field的HeaderText 屬性設置為“Product Name”,UnitPrice field設置為“Price”,同時格式化為貨幣形式。修改后,你的GridView代碼看起來應該象下面這樣:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ProductsDataSource"
EnableViewState="False">
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="ProductID"
InsertVisible="False" ReadOnly="True"
SortExpression="ProductID" />
<asp:BoundField DataField="ProductName" HeaderText="Product Name"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="Price"
SortExpression="UnitPrice" DataFormatString="{0:c}"
HtmlEncode="False" />
</Columns>
</asp:GridView>
在瀏覽器中瀏覽本頁,如圖 11所示,GridView列出了每個產品的ProductID, ProductName, 和UnitPrice。
圖 11:GridView里列出了每個產品的ProductID, ProductName, 和UnitPrice。
測試該頁面時, GridView調用其數據源控件的Select()方法。如果我們使用ObjectDataSource控件來測試該頁面的話,它將會調用邏輯層ProductsBLL class的GetProducts() 方法。而用SqlDataSource控件的話,其Select()方法將直接鏈接到要訪問的數據庫,并傳遞SelectCommand(具體就本例而言,傳遞的是SELECT [ProductID], [ProductName], [UnitPrice] FROM [Products])。SqlDataSource將返回的結果傳遞給GridView,后者根據從數據庫返回的每一條記錄生產一行(a row)
SqlDataSource控件及數據Web控件的內置屬性
一般來說,數據 Web控件的分頁,排序,編輯,插入,刪除等屬性是由數據Web控件自身指定的,跟它所使用的數據源控件沒有太大關系。也就是說, GridView可以自由的啟用它內建的分頁,排序,編輯和刪除功能,而不管它到底是綁定到SqlDataSource控件還是ObjectDataSource控件。然而,數據Web控件的某些屬性卻要受其綁定的數據源控件及其設置的影響。
比如, 就像我們在 Efficiently Paging Through Large Amounts of Data 這章教程中探討的那樣,在啟用分頁功能后,在默認情況下,每次跳轉頁面時,數據Web控件都會對所有的記錄重新檢索,盡管我們只需要顯示特定的那幾條記錄。這種模式在要檢索的數據量很大的情況下,效率會很低。不過ObjectDataSource控件可以通過自定義分頁的方法僅僅返回那些需要在當前頁面上顯示的記錄,很遺憾的是SqlDataSource控件不支持自定義分頁功能。
在默認情況下, SqlDataSource控件返回的數據可以通過GridView控件來進行分頁和排序。來做個示范,在Querying.aspx 頁面中,在GridView控件的智能標簽里啟用分頁和排序功能,看它是否象我們期望的那樣工作。
分頁和排序的原理在于SqlDataSource控件將檢索的數據庫數據轉換成“泛型數據集”(loosely-typed DataSet)。那些被用來分頁的每條記錄就蘊含
在數據集里面,此外,數據集支持對返回的結果進行排序。當 GridView請求對數據分頁或排序時,SqlDataSource控件自動完成上述工作。
在默認情況下, SqlDataSource返回的是數據集(DataSet),你也可以使它返回一個DataReader ,方法是把它的DataSourceMode屬性設置為 “ DataReader”。當希望把DataReader的檢索結果轉換為現成的代碼 ( existing code )時,設置為DataReader往往是首選。另外DataReader比起 DataSet來簡單的多,功能更強大。不過將DataSourceMode屬性設置為 “ DataReader”后,數據Web控件便不能啟用分頁或排序功能,因為 SqlDataSource無法得知總共返回了多少條記錄,并且DataReader也不支持對返回的數據排序。
第四步:使用自定義的 SQL查詢或存儲過程
前面講到, SqlDataSource控件從數據庫檢索數據的方法有2種。在第二步我們探討了從表Products返回數據的方法,現在我們探討用自定義SQL查詢的情況。
在 Querying.aspx添加一個新的GridView控件,在其智能標簽的下拉列表中
選擇“新建數據源”,在“選擇數據源類型”界面中選“ database”,將數據
源 ID設置為“ProductsWithCategoryInfoDataSource”。
圖 12:創建一個新的SqlDataSource控件,并命名為ProductsWithCategoryInfoDataSource
下一步,接著會詢問使用哪個數據連接,就想我們在圖 7做的那樣,在下拉列表中選擇NORTHWINDConnectionString,點下一步,在配置SQL語句界面中,選擇“指定自定義SQL語句或存儲過程”,點下一步,進入“定義自定義語句或存儲過程”界面,包含“選擇”,“更新”,“刪除”,“插入”四個選項卡,在每個選項卡中,你可以在文本框中輸入自定義SQL語句,或者在下拉列表中選擇存儲過程。本章我們討論輸入自定義SQL語句,在下面的教程中再探討使用存儲過程的情況。
圖 13:輸入自定義SQL語句或選擇某個存儲過程
可以手工輸入自定義 SQL 語句,也可以借助于查詢生成器來輔助生成。不管
用哪種,都應使用如下查詢:
SELECT Products.ProductID, Products.ProductName, Categories.CategoryName
FROM Categories
INNER JOIN Products ON
Categories.CategoryID = Products.CategoryID
圖 14:使用查詢生成器圖像化的構造查詢
點下一步進入“測試查詢”界面,點“完成”結束設置。
完成設置后, GridView的代碼應該看起來象下面這樣:
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID"
DataSourceID="ProductsWithCategoryInfoDataSource"
EnableViewState="False">
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="ProductID"
InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="ProductName" HeaderText="ProductName"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="CategoryName"
SortExpression="CategoryName" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="ProductsWithCategoryInfoDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand="
SELECT Products.ProductID, Products.ProductName, Categories.CategoryName
FROM Categories
INNER JOIN Products ON Categories.CategoryID = Products.CategoryID">
</asp:SqlDataSource>
http:
發表評論
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

評論