在 ADO.NET 數據集中瀏覽多個相關表
摘要 : ADO.NET 中的數據集是一種在內存中表示數據的方法,它可以包含多個相關的數據表。本文介紹了在數據集中瀏覽這些相關數據表的方法。您將在 Visual Basic .NET 或 Visual C# .NET 中創建一個 Windows 應用程序,基于選定的記錄返回相關記錄,并使用表
摘要:ADO
.NET 中的數據集是一種在內存中表示數據的方法,它可以包含多個相關的數據表。本文介紹了在數據集中瀏覽這些相關數據表的方法。您將在 Visual Basic®
.NET 或 Visual C#™ .NET 中創建一個
Windows® 應用程序,基于選定的記錄返回相關記錄,并使用表達式列為相關記錄生成合計信息。本文包含一些指向英文站點的鏈接。
簡介
由于數據集可以包含幾個相關的表,因此了解如何在父記錄和子記錄之間進行瀏覽是一項基本任務,而這并非顯而易見,特別是當您試圖訪問相關層次結構中的深層表中的數據時,更是如此。您還將學習如何瀏覽包含具有多對多關系的表的數據集,其中每個表都通過第三方表(中間表)彼此相關聯。
以下是本文所包含任務的概述:
- 創建 Windows 應用程序項目。
- 顯示用作初始選定內容的數據列表。
- 返回與選定記錄相關的記錄。
- 瀏覽多個表和多個相關結構,并在運行時直接訪問數據集中的數據。
此外,本文還介紹一些相關的任務:
- 為數據表添加基于相關數據的表達式列。
- 生成相關數據的合計信息。
前提條件
要充分理解本文,您應該具有:
- 基本的關系數據庫概念的知識。
- 與羅斯文示例數據庫的有效連接,以便您能夠創建和運行應用程序。
- 大體上熟悉 ADO.NET 數據集。
重要的數據對象
要使用數據集中的相關記錄,您應基本了解 .NET 框架 System.Data 命名空間中的幾個對象以及它們如何相互作用。這些對象協同工作以提供數據集中的導航功能。
以下對象用于表達數據集中的關系:
- DataSet - 在內存中表示數據,可以包含多個可與 DataRelation 對象相關的 DataTable 對象。
- DataTable - 表示一個完整的數據表。數據表的架構是由構成該表的 DataColumnCollection 定義的。當兩個數據表相關時,DataRelation 對象使用每個表中的 DataColumn 來關聯數據。
- DataRelation - 連接多個表,以便瀏覽相關表中的記錄。訪問相關記錄時,DataRelation 對象被傳遞給 GetChildRows 或 GetParentRow 方法。DataRelation 對象確定所要查詢的相關表,以便返回與 GetChildRows 或 GetParentRow 方法調用相關聯的相關數據。
- DataRow - 表示數據的一個單獨的記錄。用于返回相關數據的 GetChildRows 方法和 GetParentRow 方法是 DataRow 對象的成員。
- DataColumn - 表示一個單獨的字段,結合在一起時將定義 DataTable 的架構。當兩個數據表相關時,DataRelation 對象使用每個表中的數據列來關聯數據。
創建應用程序
本節將建立這一演練的起點。隨后的步驟將創建數據連接、數據適配器和包含相關表的數據集,以及幾個選擇和顯示數據的控件。
創建新的 Windows 應用程序
- 從 File(文件)菜單中,指向 New(新建),并選擇 Project(項目)。將顯示 New Project(新建項目)對話框。
- 在 Project Types(項目類型)窗格中,根據您需要的編程語言,選擇 Visual Basic Projects(Visual Basic 項目)或 Visual C# Projects(Visual C# 項目)。
- 在 Templates(模板)窗格中,選擇 Windows Application(Windows 應用程序),并將其命名為 DataRelationExample,然后單擊 OK(確定)。
DataRelationExample 項目將添加到 Solution Explorer(解決方案資源管理器)中。
連接到數據庫
此連接允許您與 Visual Studio® 集成開發環境 (IDE) 中的數據源進行通訊。
連接到 Server Explorer(服務器資源管理器)中的羅斯文示例數據庫
- 在 Server Explorer(服務器資源管理器)中,建立連接到羅斯文示例數據庫的數據連接。
- 在 Server Explorer(服務器資源管理器)中展開羅斯文數據連接,直到可以看到所有的表。
創建數據適配器和連接
此步驟創建用于在應用程序和數據源之間連接和交換數據的連接和數據適配器。
創建數據適配器和連接
- 將“客戶”表從 Server Explorer(服務器資源管理器)中拖到窗體上。組件欄中將顯示連接和數據適配器。
- 選擇 Connection(連接)并將 Name 屬性設置為 dcNorthwind。
- 選擇數據適配器并將 Name 屬性設置為 daCustomers。
- 將“訂單”表從 Server Explorer(服務器資源管理器)中拖到窗體上。組件欄中將顯示第二個數據適配器。
- 選擇新的數據適配器并將 Name 屬性設置為 daOrders。
生成數據集
使用剛剛添加到窗體上的數據適配器生成包含客戶表和訂單表的數據集。
生成將包含相關數據表的數據集
- 從 Data(數據)菜單中,選擇 Generate Dataset(生成數據集)。將顯示 Generate Dataset(生成數據集)對話框。
提示:將光標移到窗體上即可使用 Data(數據)菜單。
- 單擊 New(新建)并將數據集命名為 dsNorthwind。
- 選擇客戶表和訂單表。
- 選擇 Add this dataset to the designer(將此數據集添加到設計器)復選框,然后單擊 OK(確定)。
Solution Explorer(解決方案資源管理器)的項目中將添加一個名為 dsNorthwind.xsd 的文件,并且組件欄中將顯示該數據集的一個實例。
創建關系
生成數據集并不能自動創建數據集中各表之間的關系。關系可以通過編程創建,也可以使用 XML Designer(XML 設計器)直觀地創建。本文使用 XML Designer(XML 設計器)。
創建客戶表和訂單表之間的關系
- 在 Solution Explorer(解決方案資源管理器)中,雙擊 dsNorthwind.xsd 文件。文件將在 XML Designer(XML 設計器)中打開。
- 從工具欄的 XML Schema(XML 架構)選項卡中,將 Relation(關系)拖到訂單表上。
- 在 Edit Relation(編輯關系)對話框中,設置以下屬性:
元素 |
設置 |
Name |
CustomersOrders |
Parent |
Customers |
Child |
Orders |
Key Fields |
CustomerID |
Foreign Key Fields |
CustomerID |
- 單擊 OK(確定)以創建關系并關閉對話框。
- 從 File(文件)菜單中,選擇 Save All(全部保存)以保存該項目。
顯示數據
此應用程序使用組合框、列表框和 RTF 文本框來選擇和顯示數據。
添加選擇和顯示數據的控件
- 在 Solution Explorer(解決方案資源管理器)中,右鍵單擊 Form1(.cs 或 .vb,取決于應用程序的語言),然后從快捷菜單中選擇 View Designer(視圖設計器)。
- 在窗體的左半部,添加一個 ListBox 控件,并將其 Name 屬性設置為 lbOrders。
- 在窗體的右半部,添加一個 RichTextBox 控件,并將其 Name 屬性設置為 rtbDetails。
- 在列表框的上方,添加一個 ComboBox 控件,并將其 Name 屬性設置為 cbCustomers。
- 保存項目。

圖 1:建議的窗體控件布局
現在,可以開始向應用程序添加功能了。
設置顯示公司名稱的組合框
- 選擇組合框 (cbCustomers) 并設置以下屬性:
屬性 |
設置 |
DataSource |
DsNorthwind1 |
DisplayMember |
Customers.CompanyName |
ValueMember |
Customers.CustomerID |
用數據填充表
要用數據填充表,必須為應用程序添加代碼。
在數據集 (dsNorthwind1) 中的客戶表和訂單表中填充數據
- 雙擊窗體上的一塊空白區域,為 Form1_Load 事件創建事件處理程序。
- 添加以下代碼:
' Visual Basic Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ' 關閉數據集中的約束。 DsNorthwind1.EnforceConstraints = False
' 用數據填充表。 daOrders.Fill(DsNorthwind1) daCustomers.Fill(DsNorthwind1)
' 重新開啟約束。 DsNorthwind1.EnforceConstraints = True End Sub
// C# private void Form1_Load(object sender, System.EventArgs e) { // 關閉數據集中的約束。 dsNorthwind1.EnforceConstraints = false;
// 用數據填充表。 daOrders.Fill(dsNorthwind1); daCustomers.Fill(dsNorthwind1);
// 重新開啟約束。 dsNorthwind1.EnforceConstraints = true; } |
- 保存項目。
- 按 F5 鍵運行該應用程序?,F在組合框中包含一個公司名稱列表。
- 關閉窗體。
在兩個表中瀏覽相關記錄
這里簡要介紹一下如何在數據集中構成一對多關系的兩個表之間訪問數據。在選擇一個數據行之后,可以通過調用 GetChildRows 或 GetParentRow 方法并向該數據行傳遞適當的數據關系來返回其相關記錄。
注意:GetChildRows 方法將以 DataRow 對象數組的形式返回數據,而 GetParentRow 方法只返回一個單個的數據行。
要演示這一功能,需要給應用程序添加一些代碼,以返回組合框中選定客戶的所有訂單(子行)。更改組合框中的選定客戶會引發 ComboBox.SelectedIndexChanged 事件,列表框中將填充該選定客戶的每個訂單的訂單 ID。
您可以根據組合框中選定的客戶,調用 GetChildRows 方法。訂單表中的所有相關記錄都將分配給名為 draOrders 的數據行數組。
注意:下一節將添加在列表框中顯示相關訂單列表的功能。為確認數組中確實包含相關的記錄,數組的長度(即選定客戶的訂單總數)將顯示為窗體的標題。
創建獲取選定客戶的訂單的事件處理程序
- 在 Solution Explorer(解決方案資源管理器)中,右鍵單擊 Form1 并從快捷菜單中選擇 View Designer(視圖設計器)。
- 雙擊組合框為 SelectedIndexChanged 事件創建事件處理程序。
- 添加以下代碼:
' Visual Basic Private Sub cbCustomers_SelectedIndexChanged _ (ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles cbCustomers.SelectedIndexChanged ' 聲明一個用來保存選定客戶的客戶 ID 的字符串。 Dim SelectedCustomerID As String SelectedCustomerID = cbCustomers.SelectedValue.ToString() ' 聲明一個用來保存選定客戶的記錄的數據行。 Dim drSelectedCustomer As DataRow drSelectedCustomer = _ DsNorthwind1.Customers.FindByCustomerID _ (SelectedCustomerID)
' 聲明一個用來保存相關記錄的數據行數組。 Dim draOrders As DataRow() draOrders = drSelectedCustomer.GetChildRows("CustomersOrders") ' 在窗體標題中顯示數組的長度(訂單數) ' 和客戶 ID。 Me.Text = draOrders.Length.ToString() & " 訂單所有者 " & _ SelectedCustomerID End Sub
// C# private void cbCustomers_SelectedIndexChanged (object sender, System.EventArgs e) { // 聲明一個用來保存選定客戶的客戶 ID 的字符串。 String SelectedCustomerID; SelectedCustomerID = cbCustomers.SelectedValue.ToString();
// 聲明一個用來保存選定客戶的記錄的數據行。 DataRow drSelectedCustomer; drSelectedCustomer = dsNorthwind1.Customers.FindByCustomerID(SelectedCustomerID);
// 聲明一個用來保存相關記錄的數據行數組。 DataRow[] draOrders; draOrders = drSelectedCustomer.GetChildRows("CustomersOrders");
// 在窗體標題中顯示數組的長度(訂單數) // 和客戶 ID。 this.Text = draOrders.Length.ToString() + " 訂單所有者 " + SelectedCustomerID; } |
- 保存項目。
- 運行應用程序。
選擇另一個客戶,并檢查窗體標題。將顯示選定客戶的訂單總數及其客戶 ID。
- 關閉窗體。
顯示相關記錄
現在您已經有了選定客戶的相關記錄(存儲在數據行數組中),您可以顯示它們以便與用戶進行交互。應用程序將逐一訪問 GetChildRows 方法返回的數據行數組中的數據,并將每個相關記錄的“訂單 ID”作為單獨的項添加到列表框中。
注意:雖然此示例將逐一訪問相關數據行數組中的數據,但列表框可能已經使用屬性窗口,通過 DataSource 屬性、DataMember 屬性和 ValueMember 屬性被綁定到相關的記錄。
在列表框中顯示相關記錄
- 在 Solution Explorer(解決方案資源管理器)中,右鍵單擊 Form1 并從快捷菜單中選擇 View Code(查看代碼)。
- 在前面步驟中創建的組合框的 SelectedIndexChanged 事件處理程序中,將以下代碼添加到處理程序中已有代碼之下:
' Visual Basic ' 當更改選定客戶時,清除訂單列表。 lbOrders.Items.Clear() rtbDetails.Text = ""
' 將每個相關訂單的訂單 ID 添加到列表框中。 Dim drOrder As DataRow For Each drOrder In draOrders lbOrders.Items.Add(drOrder("OrderID")) Next
// C# // 當更改選定客戶時,清除訂單列表。 lbOrders.Items.Clear(); rtbDetails.Text = "";
// 將每個相關訂單的訂單 ID 添加到列表框中。 foreach(DataRow drOrder in draOrders) { lbOrders.Items.Add(drOrder["OrderID"]); } |
- 保存項目。
- 運行應用程序。
列表框中將顯示訂單列表。在組合框中選擇另一個客戶,訂單列表將被更新。
- 關閉窗體。
在三個或更多表中瀏覽相關記錄
瀏覽三個或更多表與處理兩個表一樣簡單。要了解如何處理兩個以上的表,請將訂單明細表和產品表添加到 dsNorthwind
數據集中。在列表框中選定一個訂單后,該訂單的詳細信息即顯示在 RTF 文本框中。
為了滿足約束規則,您需要刪除現有的數據關系,將來再重新創建。
暫時刪除 dsNorthwind 數據集中的 DataRelation
- 在 Solution Explorer(解決方案資源管理器)中,雙擊 dsNorthwind.xsd 以在 XML Designer(XML 設計器)中打開它。
- 選擇現有的 CustomersOrders 關系并將其刪除。
- 保存項目。
現在您需要將另外兩個表添加到現有數據集中,并創建新的 DataRelation 對象以將所有表連在一起。
將訂單明細表和產品表添加到 dsNorthwind 數據集中
- 在 Solution Explorer(解決方案資源管理器)中,右鍵單擊 Form1 并從快捷菜單中選擇 View Designer(視圖設計器)。
- 將“訂單明細”表從 Server Explorer(服務器資源管理器)中拖到窗體上。組件欄中將顯示一個新的數據適配器。
- 選擇該新的數據適配器并將其 Name 屬性設置為 daOrderDetails。
- 將“產品”表從 Server Explorer(服務器資源管理器)中拖到窗體上。組件欄中將顯示一個新的數據適配器。
- 選擇該新的數據適配器并將其 Name 屬性設置為 daProducts。
新表只是被添加到了窗體上,因此每次添加額外的表時,都必須重新生成數據集。
重新生成 dsNorthwind 數據集
- 從 Data(數據)菜單中,選擇 Generate Dataset(生成數據集)。
提示:將光標移到窗體上即可使用 Data(數據)菜單。
- 單擊 Existing(現有),然后選擇 dsNorthwind 數據集。
- 選擇所有四個表(客戶表、訂單表、訂單明細表和產品表)。
- 清除 Add this dataset to the designer(將此數據集添加到設計器)復選框,然后單擊 OK(確定)。將生成帶有附加表的數據集。
注意:如果出現一個對話框,其中說明“The file has been modified outside of the source editor. Do you want to reload it?”(文件已在源編輯器之外被修改。是否要重新加載?),請單擊 Yes(是)。
請記住,生成數據集并不能自動創建數據集中各表之間的關系。
創建關系
- 在 Solution Explorer(解決方案資源管理器)中,雙擊 dsNorthwind.xsd 文件。文件將在 XML Designer(XML 設計器)中打開。
- 從工具欄的 XML Schema(XML 架構)選項卡中,將 Relation(關系)拖到訂單表上。
- 在 Edit Relation(編輯關系)對話框中,設置以下屬性:
元素 |
設置 |
Name |
CustomersOrders |
Parent |
Customers |
Child |
Orders |
Key Fields |
CustomerID |
Foreign Key Fields |
CustomerID |
- 單擊 OK(確定)以創建關系并關閉對話框。
- 從工具欄的 XML Schema(XML 架構)選項卡中,將 Relation(關系)拖到訂單明細表上。
- 在 Edit Relation(編輯關系)對話框中,設置以下屬性:
元素 |
設置 |
Name |
OrdersOrderDetails |
Parent |
Orders |
Child |
OrderDetails |
Key Fields |
OrderID |
Foreign Key Fields |
OrderID |
- 單擊 OK(確定)以創建關系并關閉對話框。
- 從工具欄的 XML Schema(XML 架構)選項卡中,將 Relation(關系)拖到訂單明細表上。
- 在 Edit Relation(編輯關系)對話框中,設置以下屬性:
元素 |
設置 |
Name |
ProductsOrderDetails |
Parent |
Products |
Child |
OrderDetails |
Key Fields |
ProductID |
Foreign Key Fields |
ProductID |
- 單擊 OK(確定)以創建關系并關閉對話框。
- 保存項目。
訂單明細表和產品表已被添加到數據集中,但是您仍需要添加代碼,以便在運行時用數據來填充它們。
用數據填充表
- 在 Solution Explorer(解決方案資源管理器)中,右鍵單擊 Form1 并從快捷菜單中選擇 View Code(查看代碼)。
- 在 Form1_Load 事件處理程序中,將以下代碼添加到注釋“
用數據填充表
”與 daOrders.Fill(dsNorthwind1)
行之間:
' Visual Basic daOrderDetails.Fill(dsNorthwind1) daProducts.Fill(dsNorthwind1)
// C# daOrderDetails.Fill(dsNorthwind1); daProducts.Fill(dsNorthwind1); |
用數據填充 RTF 文本框
現在您要為項目添加代碼,以便在列表框中選定某個訂單時,可以在 RTF 文本框中顯示所有訂單明細。
以下代碼將基于列表框中的選定訂單調用 GetChildRows 方法。訂單明細表中的所有相關記錄都將分配給名為 draOrderDetails
的數據行數組。每個數據行的內容將顯示在 RTF 文本框中。
注意:請注意嵌套的 For Each 循環是如何首先選取一個數據行,然后在該數據行的所有列中循環以訪問整個相關記錄的。
設置 RTF 文本框以顯示所有訂單明細
- 在 Solution Explorer(解決方案資源管理器)中,右鍵單擊 Form1 并從快捷菜單中選擇 View Designer(視圖設計器)。
- 雙擊列表框為列表框 lbOrders 的 SelectedIndexChanged 事件創建事件處理程序。
- 添加以下代碼:
' Visual Basic Private Sub lbOrders_SelectedIndexChanged _ (ByVal sender As System.Object, ByVal e As System.EventArgs) _ Handles lbOrders.SelectedIndexChanged ' 選擇新訂單時,清除 RTF 文本框。 rtbDetails.Clear()
' 聲明一個用來保存選定的訂單 ID 的整數。 Dim SelectedOrderID As Integer ' 將選定的項目設置為整數。 SelectedOrderID = CType(lbOrders.SelectedItem, Integer)
' 聲明一個用來保存選定訂單的記錄的數據行。 Dim drSelectedOrder As DataRow drSelectedOrder = _ DsNorthwind1.Orders.FindByOrderID(SelectedOrderID)
' 聲明一個用來保存相關記錄的數據行數組。 Dim draOrderDetails() As DataRow draOrderDetails = _ drSelectedOrder.GetChildRows("OrdersOrderDetails")
Dim details As String = "" Dim drDetails As DataRow Dim dcDetails As DataColumn For Each drDetails In draOrderDetails For Each dcDetails In drDetails.Table.Columns details &= dcDetails.ColumnName & ": " details &= drDetails(dcDetails).ToString() details &= ControlChars.CrLf Next details &= ControlChars.CrLf Next rtbDetails.Text = details End Sub
// C# private void lbOrders_SelectedIndexChanged (object sender, System.EventArgs e) { // 選擇新訂單時,清除 RTF 文本框。 rtbDetails.Clear();
// 聲明一個用來保存選定的訂單 ID 的整數。 int SelectedOrderID; // 將選定的項目設置為整數。 SelectedOrderID = (int)lbOrders.SelectedItem;
// 聲明一個用來保存選定訂單的記錄的數據行。 DataRow drSelectedOrder; drSelectedOrder = dsNorthwind1.Orders.FindByOrderID(SelectedOrderID);
// 聲明一個用來保存相關記錄的數據行數組。 DataRow[] draOrderDetails; draOrderDetails = drSelectedOrder.GetChildRows("OrdersOrderDetails");
string details = ""; foreach(DataRow drDetails in draOrderDetails) { foreach(DataColumn dcDetails in drDetails.Table.Columns) { details += dcDetails.ColumnName + ": "; details += drDetails[dcDetails].ToString() + "\n"; } details += "\n"; } rtbDetails.Text = details; } |
- 保存項目。
- 運行應用程序。
- 在列表框中選擇一個訂單,其訂單明細將顯示在 RTF 文本框中。
- 在列表框中選擇另一個訂單。RTF 文本框中的訂單明細將被更新。
瀏覽多對多關系
構成多對多關系的表通常通過保證數據完整性的第三方表進行連接。在羅斯文數據庫中,訂單表和產品表就是這樣相關的。因為有些訂單可能包含很多產品,而有些產品又在很多訂單中銷售。這兩個表是通過訂單明細表連接的,訂單明細表利用這兩個表中的列建立自己特定的列,并使這些數據相關。瀏覽構成多對多關系的三個表與處理一對多關系的表并沒有太大區別。
要瀏覽多對多關系,您可以基于訂單明細表中的單個記錄來訪問產品,這將返回產品名稱并顯示在訂單明細中。
您可以使用 GetParentRow 方法從產品表中訪問產品名稱。調用 GetParentRow 方法將返回單個數據行,而調用 GetChildRows 方法將返回數據行數組(如上例所示)。
從訂單明細記錄中獲取產品名稱
- 在 Solution Explorer(解決方案資源管理器)中,右鍵單擊 Form1 并從快捷菜單中選擇 View Code(查看代碼)。
- 在列表框 (lbOrders) 的 SelectedIndexChanged 事件處理程序中,將以下代碼添加到 For Each 行之間:
' Visual Basic details &= "產品名稱: " & _ CType(drDetails.GetParentRow("ProductsOrderDetails") _ ("ProductName"), String) & ControlChars.CrLf
// C# details += "產品名稱: " + drDetails.GetParentRow("ProductsOrderDetails")["ProductName"] + "\n"; |
- 保存項目。
- 運行應用程序。
- 在列表框中選擇一個訂單,
RTF 文本框中將顯示產品名稱和詳細信息?,F在窗體中顯示來自所有四個表的相關數據。
圖 2:顯示產品名稱和訂單明細的窗體
- 在列表框中選擇另一個訂單。RTF 文本框中的訂單明細將被更新。
- 關閉窗體。
表達式列
除了包含靜態數據外,還可以基于表達式的結果為 DataColumn 分配值。表達式是一個分配給 DataColumn.Expression 屬性的字符串。
當表達式與相關數據一同使用時,數據列可以包含:
- 相關數據列的計算所得值。
- 相關數據列的合計信息。
- 相關數據的邏輯比較結果。
為說明處理相關數據時的值表達式列,我們將針對每種使用情況介紹一個示例,并添加到 DataRelationExample 應用程序中。
添加包含計算值的表達式列
計算的列包含數學運算結果??梢詮默F有的列中取值進行計算。訂單明細表中將添加一個名為 Total 的新列,它將包含由表達式 UnitPrice * Quantity
返回的值(訂單的總計美元值)。
添加表達式列
- 在 Solution Explorer(解決方案資源管理器)中,右鍵單擊 Form1 并從快捷菜單中選擇 View Code(查看代碼)。
- 將以下代碼添加到 Form1_Load 事件處理程序中已有代碼之上:
' Visual Basic ' 在訂單明細表中創建名為 Total 的表達式列。 Dim dcTotal as DataColumn = new DataColumn("Total") dcTotal.DataType = System.Type.GetType("System.Decimal") dcTotal.Expression = "UnitPrice * Quantity" DsNorthwind1.Order_Details.Columns.Add(dcTotal)
// C# // 在訂單明細表中創建名為 Total 的表達式列。 DataColumn dcTotal = new DataColumn("Total"); dcTotal.DataType = System.Type.GetType("System.Decimal"); dcTotal.Expression = "UnitPrice * Quantity"; dsNorthwind1.Order_Details.Columns.Add(dcTotal); |
- 運行應用程序。
- 在列表框中選擇一個訂單,
檢查 RTF 文本框中的訂單明細,并注意每個記錄都有一個新的 Total 列,顯示 UnitPrice 和 Quantity 字段的乘積。
- 關閉窗體。
添加包含合計信息的表達式列
Expression 屬性支持幾個合計功能(Sum、Avg、Count 等)。有關詳細信息,請參閱 lrfSystemDataDataColumnClassExpressionTopic.asp">DataColumn.Expression 屬性。
為演示如何生成合計信息,需要在訂單表中添加一個名為 OrderTotal 的新列。此列將使用 Sum 功能,根據在列表框 (lbOrders) 中選定的訂單返回所有子訂單明細記錄的總計美元值。然后,該值將顯示在 RTF 文本框中每個訂單明細的上方。
創建 OrderTotal 列
- 在 Solution Explorer(解決方案資源管理器)中,右鍵單擊 Form1 并從快捷菜單中選擇 View Code(查看代碼)。
- 在 Form1_Load 事件處理程序中,將以下代碼添加到在訂單明細表中創建 Total 列的代碼的下方:
' Visual Basic ' 在訂單表中創建名為 OrderTotal 的表達式列。 Dim dcOrderTotal as DataColumn = new DataColumn("OrderTotal") dcOrderTotal.DataType = System.Type.GetType("System.Decimal") dcOrderTotal.Expression = "Sum(Child.Total)" DsNorthwind1.Orders.Columns.Add(dcOrderTotal)
// C# // 在訂單表中創建名為 OrderTotal 的表達式列。 DataColumn dcTotal2 = new DataColumn("OrderTotal"); dcTotal2.DataType = System.Type.GetType("System.Decimal"); dcTotal2.Expression = "Sum(Child.Total)"; dsNorthwind1.Orders.Columns.Add(dcTotal2); |
將合計信息顯示在所有訂單明細的上方
- 在 lbOrders_SelectedIndexChanged 事件處理程序中,將以下代碼添加到
Dim details As String = ""
或 string details = ""
行之下:
' Visual Basic details = "訂單總計: " & String.Format("{0:c}", _ DsNorthwind1.Orders.FindByOrderID(CType(lbOrders.SelectedItem, _ Integer))("OrderTotal")) & ControlChars.CrLf
// C# details = "訂單總計: " + String.Format("{0:c}",dsNorthwind1.Orders.FindByOrderID ((int)lbOrders.SelectedItem)["OrderTotal"]) + "\n"; |
- 運行應用程序。
- 在列表框中選擇一個訂單,
請注意,選定訂單的所有訂單明細的總計金額將顯示在 RTF 文本框中的第一行。
- 在列表框中選擇另一個訂單,將更新顯示以反映新選擇的訂單。
- 關閉窗體。
添加包含邏輯求值的表達式列
Expression 屬性可以基于其他列中的計算值來填充某個數據列。例如,訂單表中的 OrderSize 列可以包含值“Big”(如果訂單總額大于 1000)或者“Small”(如果訂單總額小于 1000)。
為演示這類表達式,需要在 DataRelationExample 應用程序中添加代碼以執行以下操作:
- 在訂單表中添加名為 OrderSize 的數據列。
- 根據相關訂單明細的值來填充 OrderSize 列。
- 在 RTF 文本框的頂部同時顯示 OrderSize 列的值和 OrderTotal 的值。
添加創建 OrderSize 列的代碼
- 在 Solution Explorer(解決方案資源管理器)中,右鍵單擊 Form1 并從快捷菜單中選擇 View Code(查看代碼)。
- 在 Form1_Load 事件處理程序中,將以下代碼添加到在訂單表中創建 OrderTotal 列的代碼的下方:
' Visual Basic ' 在訂單表中創建名為 OrderSize 的表達式列。 Dim dcOrderSize as DataColumn = new DataColumn("OrderSize") dcOrderSize.DataType = System.Type.GetType("System.String") dcOrderSize.Expression = "IIF(Sum(Child.Total)<1000,'Small','Big')" DsNorthwind1.Orders.Columns.Add(dcOrderSize)
// C# // 在訂單表中創建名為 OrderSize 的表達式列。 DataColumn dcOrderSize = new DataColumn("OrderSize"); dcOrderSize.DataType = System.Type.GetType("System.String"); dcOrderSize.Expression = "IIF(Sum(Child.Total)<1000,'Small','Big')"; dsNorthwind1.Orders.Columns.Add(dcOrderSize); |
顯示 OrderSize 的值
- 在 lbOrders_SelectedIndexChanged 事件處理程序中,將以下代碼添加到第一個 For Each 行的上方:
' Visual Basic details &= " (" & CType(DsNorthwind1.Orders.FindByOrderID _ (CType(lbOrders.SelectedItem, Integer))("OrderSize"), String) & ")" _ & ControlChars.CrLf
// C# details += " (" + dsNorthwind1.Orders.FindByOrderID ((int)lbOrders.SelectedItem)["OrderSize"] + ")\n"; |
- 運行應用程序。
- 在列表框中選擇一個訂單。
- 檢查 RTF 文本框中的第一行。選定訂單的 OrderSize 將顯示在 OrderTotal 的右側。
- 在列表框中選擇另一個訂單,將更新顯示以反映新選擇的訂單。
- 從 Debug(調試)菜單中,選擇 Stop Debugging(停止調試)。
有關相關表的其他信息
這里有必要提及一些其他信息以豐富本文的內容。
填充相關數據表的順序非常重要
相關數據表的填充順序對數據的輸出有很大影響,因此必須在設計應用程序時予以考慮。例如,請注意最后一個填充的客戶表的情況。當填充客戶表時,組合框將填充客戶名稱值。填充組合框時,會引發 SelectedIndexChanged 事件。這將執行事件處理程序中的代碼。由于尚未填充訂單表,GetChildRows 方法將返回零 (0) 個記錄,窗體的標題將顯示錯誤信息。試一試:更改代碼以首先填充客戶表,并運行應用程序。窗體的標題顯示 ALFKI 的零 (0) 個訂單,這是不正確的。
返回相關記錄的特定版本
通過將所需的 DataRowVersion 作為第二個(可選的)參數傳遞給 GetChildRows 或 GetParentRow 方法,可以返回數據行的特定版本。以該應用程序為例,如果只想查看特定客戶的原始訂單,可以將組合框的 SelectedIndexChanged 事件中的代碼更改為類似如下的代碼。由于此應用程序中的數據并未更改,以下代碼不會產生明顯的效果,這里只是作為一個說明。
' Visual Basic ' 只用選定客戶的原始子行 ' 填充數組。 Dim draOrders As DataRow() = DsNorthwind1.Customers.FindByCustomerID _ (cbCustomers.SelectedValue.ToString()).GetChildRows _ ("CustomersOrders", DataRowVersion.Original)
// C# // 只用選定客戶的原始子行 // 填充數組。 DataRow draOrders = dsNorthwind1.Customers.FindByCustomerID (cbCustomers.SelectedValue.ToString()).GetChildRows ("CustomerOrders", DataRowVersion.Original); |
總結
要訪問特定數據行的相關記錄,可以調用該行的 GetChildRows 或 GetParentRow 方法,以傳遞連接該數據行及其相關記錄的數據關系。然后,便可以通過檢查由該方法調用返回的數據行(或數據行數組)來訪問相關的記錄。
通過為 DataColumn.Expression 屬性分配一個有效的表達式字符串并將數據列添加到相應的 DataTable.Columns 集合中,可以對相關記錄中的值進行計算,合計和邏輯求值。
原文轉自:http://www.anti-gravitydesign.com
- 評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
-
国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97
|