ADO.NET中容易混淆的概念是什么

本篇文章給大家分享的是有關(guān)ADO.NET中容易混淆的概念是什么,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

創(chuàng)新互聯(lián)建站專注于思明網(wǎng)站建設(shè)服務及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供思明營銷型網(wǎng)站建設(shè),思明網(wǎng)站制作、思明網(wǎng)頁設(shè)計、思明網(wǎng)站官網(wǎng)定制、微信小程序定制開發(fā)服務,打造思明網(wǎng)絡公司原創(chuàng)品牌,更為您提供思明網(wǎng)站排名全網(wǎng)營銷落地服務。

一、DataTable

DataTable表示內(nèi)存中數(shù)據(jù)的一個表,它完全是在內(nèi)存中的一個獨立存在,包含了這張表的全部信息。DataTable可以是從通過連接從數(shù)據(jù)庫中讀取出來形成的一個表,一旦將內(nèi)容讀到DataTable中,此DataTable就可以跟數(shù)據(jù)源斷開而獨立存在;也可以是完全由程序自己通過代碼來建立的一個表。

◆ DataColumn

一個表是由行和列組成的一個兩維的結(jié)構(gòu)。表的結(jié)構(gòu)是由DataColumn對象的集合組成,DataColumn對象集合可由DataTable.Columns屬性中能獲取到,通過定義每一列的數(shù)據(jù)類型來確定表的架構(gòu),類似數(shù)據(jù)庫中定義表。定義完表的結(jié)構(gòu)就可以根據(jù)結(jié)構(gòu)來生成DataRow,用DataTable.NewRow()方法來生成此DataTable結(jié)構(gòu)的新行。

一個DataTable是由DataRow的集合組成的,DataRow的集合這個可以由DataTable.Rows屬性來訪問。

DataTable還可以通過現(xiàn)有的列用Expression屬性的表達式創(chuàng)建一些列。

1、創(chuàng)建計算出的列

比如:已經(jīng)有了一個表結(jié)構(gòu),表中有一個DataColumn的集合,其中有一個叫UnitPrice的列,你可以新建一個DataColumn,設(shè)置好ColumnName,再設(shè)置此列的表達式,DataColumn.Expression="UnitPrice * 0.086",這個列的值就是名字為UnitPrice的列計算出來的,在創(chuàng)建表達式時,使用ColumnName屬性來引用列。

2、第二個用途是創(chuàng)建聚合列

聚合列聚合通常沿著關(guān)系執(zhí)行(有關(guān)關(guān)系的描述見下面DataRelation部分),如果order表有名為detail 的子表,兩個表之間通過order.orderid和detail.orderid兩個列建立一個關(guān)系DataRelation對象名為“order2detail”,在主表order中就可以建立一個聚合列,將計算每個order在detail表中含有的所有item的價格的和:DataColumn.Expression = “sum(child(order2detail).price)",child(order2detail)表示通過關(guān)系order2detail聯(lián)系到的子表,child(order2detail).price就表示子表的price列。

◆ DataRow

DataRow對象沒有直接在代碼中使用的構(gòu)造函數(shù),一般是從具有一定結(jié)構(gòu)的DataTable用NewRow()方法來新建一個DataRow對象。一個DataRow根據(jù)其是獨立的,還是屬于某個DataTable,是否修改過,是否被DataTable刪除等等不同的情況有不同的狀態(tài),由DataRow.RowState屬性公開,如下表:


成員名稱 說明

Added該行已添加到DataRowCollection中,AcceptChanges 尚未調(diào)用。Deleted該行已通過DataRow的Delete方法被刪除。

Deleted 該行已通過DataRow的Delete方法被刪除。

Detached 該行已被創(chuàng)建,但不屬于任何DataRowCollection。DataRow 在以下情況下立即處于此狀態(tài):創(chuàng)建之后添加到集合中之前;或從集合中移除之后。

Modified 該行已被修改,AcceptChanges 尚未調(diào)用。

Unchanged 該行自上次調(diào)用 AcceptChanges 以來尚未更改。

一個DataRow對象剛被創(chuàng)建之后其狀態(tài)是Detached,是孤立的一個存在,所以建立了DataRow之后在DataRow中的單元填充了數(shù)據(jù)后還要通過DataTable.Rows.Add(DataRow)方法將此DataRow添加到DataTable,DataRow添加到DataTable后, 這個DataRow的狀態(tài)就轉(zhuǎn)變?yōu)锳dded。當修改了這個DataRow后,這個DataRow狀態(tài)轉(zhuǎn)為Modified,當用DataRow.Delete()方法刪除DataRow后,DataRow狀態(tài)將轉(zhuǎn)為Deleted,不過此行還存在在DataTable中的,只是狀態(tài)改變了,這時用DataTable.Rows.Count查看行數(shù),跟刪除前是一樣的。只有在調(diào)用了DataTable.Remove(DataRow)方法后,此DataRow才被從DataTable移除,狀態(tài)也回復到Detached孤立狀態(tài)。

一旦調(diào)用了DataTable.AcceptChanges()方法后,所有的行將根據(jù)不同的狀態(tài)做不同的處理,Added、Modified、Unchanged將保留當前值,Deleted的行將從DataTable中移除,***所有的行的狀態(tài)都置為Unchanged。當DataTable是從DataAdapter.Fill(DataSet,DataTable)方法填充而形成的,F(xiàn)ill()方法將自動調(diào)用AcceptChanges()方法,將DataTable的行狀態(tài)都置為Unchanged。并且,如果Fill方法中指定的那個DataTable在要填充的那個DataSet不存在時,會生成一個跟數(shù)據(jù)源表同樣的結(jié)構(gòu)的DataTable并填充數(shù)據(jù)。

◆ DataRelation

表示兩個DataTable對象之間的父/子關(guān)系??梢灶惐扔跀?shù)據(jù)庫中的表之間的關(guān)系,父表相當于關(guān)系列為主鍵的表,子表相當于關(guān)系列為外鍵的表。DataRelation 構(gòu)造函數(shù)一般為:DataRelation(String, DataColumn, DataColumn) ,string為關(guān)系名,***個DataColumn為建立關(guān)系的父表列,第二個DataColumn為建立關(guān)系的子表列,建立關(guān)系的兩個列的 DataType 值必須相同。

建立好了關(guān)系,必須把這個關(guān)系加入到DataTable的ParentRelations屬性或ChildRelations 屬性,這兩個屬性包含這個表的所有的跟父表的關(guān)系和跟子表的關(guān)系。若關(guān)系中此表是父表則將此關(guān)系加入到ChildRelations集合中,否則加入到ParentRelations集合中。

二、DataView

DataView表示用于排序、篩選、搜索、編輯和導航的 DataTable 的可綁定數(shù)據(jù)的自定義視圖。可以將DataView同數(shù)據(jù)庫的視圖類比,不過有點不同,數(shù)據(jù)庫的視圖可以跨表建立視圖,DataView則只能對某一個DataTable建立視圖。DataView一般通過DataTable.DefaultView 屬性來建立,再通過通過RowFilter 屬性和RowStateFilter 屬性建立這個DataTable的一個子集。

RowFilter屬性用來篩選要查看DataTable中哪些行的表達式,這個表達式同上面所說的建立計算列的表達式相同。例如:"LastName = 'Smith'",這就是只查看列LastName的值為'Smith'的那些數(shù)據(jù)行。

RowStateFilter 屬性用來設(shè)置DataView中的行狀態(tài)篩選器,上面介紹DataRow時介紹了DataRow的狀態(tài),一個DataRow可能有五種狀態(tài),RowStateFilter就是可以通過這些狀態(tài)來篩選要查看的行集。其實DataRow不僅有五種狀態(tài),DataRow還有版本的問題,比如當DataRow的狀態(tài)為Modified,即這行已經(jīng)被修改了,這時這個DataRow就會有兩個版本,Current版本和Original版本(修改前的)。實際上RowStateFilter屬性是綜合了DataRow的狀態(tài)和版本來篩選的(RowStateFilter確省值是CurrentRows)見下表:

成員名稱/說明

Added:一個新行。

CurrentRows:包括未更改行、新行和已修改行的當前行。

Deleted:已刪除的行。

ModifiedCurrent:當前版本,原始數(shù)據(jù)(請參閱ModifiedOriginal)的修改版本。

ModifiedOriginal:原始版本(盡管它后來已被修改并以ModifiedCurrent 形式存在)。

None:無。

OriginalRows:包括未更改行和已刪除行的原始行。

Unchanged:未更改的行。

DataView.Count屬性得到的計數(shù)是在應用了 RowFilter 和 RowStateFilter 之后,獲取 DataView 中記錄的數(shù)量。

DataView是建立在DataTable基礎(chǔ)上的,DataView.Table 屬性可以得到此DataView對應的那個DataTable。DataView的行叫DataRowView,可以從DataRowView直接通過DataRowView.Row 屬性得到此DataRowView對應的DataRow。

三、DataGrid

這里說的DataGrid是winform中的DataGrid,一般都是跟DataView綁定來顯示DataTable中的數(shù)據(jù),和修改DataTable中的數(shù)據(jù)。

DotNet的DataGrid的功能強大,可是在使用上與以前的習慣不太一樣,有時還比較麻煩,所以很多人都對這個DataGrid感到有些摸不著頭腦,有一種無從下手的感覺,其實把一些概念搞清楚了許多問題就會迎刃而解了。

DataGrid通過DataSource和DataMember 屬性來綁定其要顯示的數(shù)據(jù)源。數(shù)據(jù)源一般是DataTable、DataView、DataSet等,不過將這些數(shù)據(jù)源綁定到DataGrid時實際上是綁定的DataView。若數(shù)據(jù)源是DataTable時,實際上是綁定了此DataTable的DefaultView,若數(shù)據(jù)源是DataSet時,則可以向DataMember屬性設(shè)置一個字符串,該字符串指定要綁定到的表,然后再將DataMember指定的那個DataTable的DefaultView綁定到DataGrid。

所以DataGrid實際顯示的是DataTable經(jīng)過篩選的DataView。

◆ DataGrid以何種方式顯示DataView的數(shù)據(jù)

DataGrid綁定到一個DataView后,由DataGrid.TableStyles中的DataGridTableStyle 對象的集合來控制這個DataView的哪些列要顯示,列的寬度多少,列標頭的文本是什么等等。確省的DataGrid.TableStyles中不包含任何對象,這時DataGrid將會按照DataView列的順序?qū)⑺械牧卸硷@示出來。一般應用中都會設(shè)置TableStyles來控制顯示的內(nèi)容及格式。

例如DataGrid綁定到一張叫order的DataTable,這個DataTable包含了OrderID、CustomerID、OrderDate、ShipName、ShipAddress等字段,可以看到DataGrid將會按照DataView列的順序?qū)⑺械牧卸硷@示出來

我們只想顯示OrderID、CustomerID、OrderDate這三個字段,并且想將OrderID的列表頭顯示為“訂單號”,CustomerID顯示為“客戶號”,OrderDate顯示為“訂單日期”,這就要用TableStyles來控制了。

新建一個TableStyle,將此TableStyle.MappingName屬性對應到這個TableStyle要控制的那個DataTable的名字:

DataGridTableStyle myTableStyle = new DataGridTableStyle();

myTableStyle.MappingName = "myDateTable";

再建立三個DataGridColumnStyle,分別用來控制將要顯示的三個列:

DataGridColumnStyle myColumnStyle1 = new DataGridTextBoxColumn(); 
myColumnStyle1.MappingName = "OrderID"; 
myColumnStyle1.HeaderText = "訂單號"; 

DataGridColumnStyle myColumnStyle2 = new DataGridTextBoxColumn(); 
myColumnStyle2.MappingName = "CustomerID"; 
myColumnStyle2.HeaderText = "客戶號"; 

DataGridColumnStyle myColumnStyle3 = new DataGridTextBoxColumn(); 
myColumnStyle3.MappingName = "OrderDate"; 
myColumnStyle3.HeaderText = "訂單日期"; 

將這三個DataGridColumnStyle添加到TableStyle中: 

myTableStyle.GridColumnStyles.Add(myColumnStyle1); 
myTableStyle.GridColumnStyles.Add(myColumnStyle2); 
myTableStyle.GridColumnStyles.Add(myColumnStyle3);

***將TableStyle添加到DataGrid中:

dataGrid1.TableStyles.Add(myTableStyle);

將TableStyle添加到DataGrid后,再綁定數(shù)據(jù)源。

◆ DataGrid的編輯修改

DataGrid支持對DataGrid所顯示的DataTable的編輯修改,只要DataGrid的ReadOnly屬性為False,就可以在DataGrid中直接修改單元中的內(nèi)容,修改完后數(shù)據(jù)將直接反應到此DataGrid對應的那個DataTable的單元。

如果這個DataTable是通過vs.net的可視化數(shù)據(jù)設(shè)計器新建DataAdapter,并生成了SelectCommand、InsertCommand、UpdateCommand、DeleteCommand這四個命令,用DataAdapter的Fill方法得來的,那么事情就簡單了,修改過的DataTable你可以直接用DataAdapter的UpDate方法寫回到數(shù)據(jù)庫。下面看一下vs.net的可視數(shù)據(jù)數(shù)據(jù)器生成的InsertCommand命令:

this.sqlInsertCommand1.CommandText = @"INSERT INTO Customers
(CustomerID, CompanyName, ContactName, ContactTitle, Address, 
City, Region, PostalCode, Country, Phone, Fax)
VALUES (@CustomerID, @CompanyName, @ContactName, @ContactTitle,
@Address, @City, @Region, @PostalCode, @Country, @Phone, @Fax);
SELECT CustomerID, CompanyName, ContactName, ContactTitle, Address, 
City, Region, PostalCode, Country, Phone,
Fax FROM Customers WHERE (CustomerID = @CustomerID)";
this.sqlInsertCommand1.Connection = this.sqlConnection2; 
this.sqlInsertCommand1.Parameters.Add
(new System.Data.SqlClient.SqlParameter
("@CustomerID", System.Data.SqlDbType.NVarChar, 5, "CustomerID"));
this.sqlInsertCommand1.Parameters.Add
(new System.Data.SqlClient.SqlParameter
("@CompanyName", System.Data.SqlDbType.NVarChar, 40, "CompanyName")); 
this.sqlInsertCommand1.Parameters.Add
(new System.Data.SqlClient.SqlParameter
("@ContactName", System.Data.SqlDbType.NVarChar, 30, "ContactName")); 
this.sqlInsertCommand1.Parameters.Add
(new System.Data.SqlClient.SqlParameter
("@ContactTitle", System.Data.SqlDbType.NVarChar, 30, "ContactTitle")); 
this.sqlInsertCommand1.Parameters.Add
(new System.Data.SqlClient.SqlParameter
("@Address", System.Data.SqlDbType.NVarChar, 60, "Address")); 
this.sqlInsertCommand1.Parameters.Add
(new System.Data.SqlClient.SqlParameter
("@City", System.Data.SqlDbType.NVarChar, 15, "City")); 
this.sqlInsertCommand1.Parameters.Add
(new System.Data.SqlClient.SqlParameter
("@Region", System.Data.SqlDbType.NVarChar, 15, "Region")); 
this.sqlInsertCommand1.Parameters.Add
(new System.Data.SqlClient.SqlParameter
("@PostalCode", System.Data.SqlDbType.NVarChar, 10, "PostalCode")); 
this.sqlInsertCommand1.Parameters.Add
(new System.Data.SqlClient.SqlParameter
("@Country", System.Data.SqlDbType.NVarChar, 15, "Country")); 
this.sqlInsertCommand1.Parameters.Add
(new System.Data.SqlClient.SqlParameter
("@Phone", System.Data.SqlDbType.NVarChar, 24, "Phone")); 
this.sqlInsertCommand1.Parameters.Add
(new System.Data.SqlClient.SqlParameter
("@Fax", System.Data.SqlDbType.NVarChar, 24, "Fax"));

DataAdapter的SelectCommand是用來DataAdapter.Fill()方法來填充DataTable的,SelectCommand選擇的數(shù)據(jù)表行集將被填充到DataTable中,然后DataGrid將它顯示出來。

DataGrid在經(jīng)過編輯修改后,其對應的DataTable中的行就可能出現(xiàn)文章上面所述的那五種狀態(tài),可能是新加的(Added),可能是修改了的(Modified),可能是刪除的(Deleted),DataAdapter.UpDate()方法將通過調(diào)用InsertCommand命令將狀態(tài)為Added的行插入到數(shù)據(jù)庫,UpdateCommand將狀態(tài)為Modified的行在數(shù)據(jù)庫中做修改,DeleteCommand將狀態(tài)為Deleted的行在數(shù)據(jù)庫真正的刪除。

如果不是通過vs.net的可視化數(shù)據(jù)設(shè)計器新建DataAdapter,沒有自動生成SelectCommand、InsertCommand、UpdateCommand、DeleteCommand這四個命令,那么就可能需要自己寫InsertCommand、UpdateCommand、DeleteCommand命令,有一種情況就是當SelectCommand至少返回一個主鍵列或唯一的列時,可以通過SqlCommandBuilder來自動根據(jù)SelectCommand命令來自動生成另外三個更新命令,例如:

SqlConnection myConn = new SqlConnection(myConnection); 
SqlDataAdapter myDataAdapter = new SqlDataAdapter(); 
myDataAdapter.SelectCommand = new SqlCommand(mySelectQuery, myConn);
//建立DataAdapter的SelectCommand命令 
SqlCommandBuilder custCB = new SqlCommandBuilder(myDataAdapter);
//建立此DataAdapter的CommandBuilder, 
//這樣系統(tǒng)就會給此DataAdapter自動生成
InsertCommand、UpdateCommand、DeleteCommand三個命令。

否則,要用DataAdapter.UpDate()方法更新數(shù)據(jù)庫就要自己寫InsertCommand、UpdateCommand、DeleteCommand這三個命令,可以參考上面給出的vs.net自動生成的InsertCommand命令的寫法。

◆ 數(shù)據(jù)綁定的同步

WinForm中很多控件都可以與數(shù)據(jù)源綁定,綁定又分兩種情況:

簡單數(shù)據(jù)綁定

簡單數(shù)據(jù)綁定指將一個控件綁定到單個數(shù)據(jù)元素(如數(shù)據(jù)集表的列中的值)的能力。這是用于控件,如 TextBox 控件或 Label 控件(即通常只顯示單個值的控件)的典型綁定類型。事實上,控件上的任何屬性都可以綁定到數(shù)據(jù)庫中的字段。

復雜數(shù)據(jù)綁定

復雜數(shù)據(jù)綁定指將一個控件綁定到多個數(shù)據(jù)元素的能力,通常綁定到數(shù)據(jù)庫中的多條記錄,或者綁定到多個任何其他類型的可綁定數(shù)據(jù)元素,一般是綁定到一個DataView。支持復雜綁定的控件的示例有DataGrid、ListBox 和 ErrorProvider 控件。

一般DataGrid控件都是跟一個DataView綁定,DataGrid的數(shù)據(jù)綁定屬于復雜綁定,因為它綁定到有多條記錄的表,DataGrid有兩個屬性同數(shù)據(jù)綁定有關(guān):

DataGrid.DataSource 屬性:獲取或設(shè)置DataGrid所顯示數(shù)據(jù)的數(shù)據(jù)源。一般是跟DataTable 、DataView 、DataSet 綁定,如果DataSource設(shè)定為DataSet,則引用包含的表不止一個,則必須向 DataMember 屬性設(shè)置一個字符串,該字符串指定要綁定到的表。

DataGrid.DataMember 屬性:獲取或設(shè)置 DataSource中的特定列表,就是上述DataSource設(shè)定為DataSet時,要設(shè)定此屬性來指定要綁定到的表。

經(jīng)常有這種需求,一個窗體中有一個DataGrid,顯示了一些數(shù)據(jù),窗體上還有一些TextBox控件,用來顯示DataGrid中的當前行的數(shù)據(jù),一個TextBox控件對應DataGrid行的一個列,當DataGrid的當前行移動時,TextBox控件中的值也會跟著顯示改變后的DataGrid的當前行。

要保證這些數(shù)據(jù)綁定控件保持同步就要一個統(tǒng)一管理數(shù)據(jù)綁定的機制來保證這些控件的同步,DotNet中負責數(shù)據(jù)同步的是BindingManagerBase,它是用來管理數(shù)據(jù)源的,綁定到同一個數(shù)據(jù)源的數(shù)據(jù)綁定控件都可以由BindingManagerBase統(tǒng)一管理。BindingManagerBase可以由Form.BindingContext.Item屬性獲得,此屬性有兩種重載:

public BindingManagerBase this[object DataSource]
//獲取與指定數(shù)據(jù)源關(guān)聯(lián)的 BindingManagerBase 
public BindingManagerBase this[object DataSource, string DataMember]
//獲取與指定數(shù)據(jù)源和數(shù)據(jù)成員相關(guān)聯(lián)的一個 BindingManagerBase

所有的數(shù)據(jù)綁定控件的數(shù)據(jù)源同建立BindingManagerBase時傳遞的對象一樣的,都將屬于這個BindingManagerBase管理,比如,建立一個如下的BindingManagerBase:

BindingManagerBase myBindingManagerBaseParent = this.BindingContext[myDataSet,"customers"];

如果Form上有個DataGrid的DataGrid.DataSource = myDataSet;DataGrid.DataMember = "customers",那么這個DataGrid的數(shù)據(jù)源就在myBindingManagerBaseParent的管理之下了。

同樣簡單數(shù)據(jù)綁定的控件的DataSource也是跟 BindingManagerBase的DataSource一樣,DataMember是BindingManagerBase的DataMember指定的那個表的某一列時,這個控件的數(shù)據(jù)源也在這個myBindingManagerBaseParent管理之下了:

dataGrid1.DataSource = myDataSet; 
dataGrid1.DataMember = "customers"; 
textCustomerId.DataBindings.Add
(new Binding("Text",myDataSet,"customers.customerid"));
//TextBox的Text屬性跟 
//myDataSet的customers表的customerid字段綁定

BindingManagerBase控制的數(shù)據(jù)源有個當前行的概念,控件一旦跟數(shù)據(jù)源綁定后,DataGrid將顯示數(shù)據(jù)源表的所有數(shù)據(jù),不過在DataGrid的行標頭里有個黑色的三角箭頭用來指示當前行。簡單綁定控件中顯示的值將是數(shù)據(jù)源當前行的內(nèi)容。

所以,只要我們改變BindingManagerBase的指針就行了,這個可以在界面上通過點擊要到的那一行來改變當前行,也可以在程序中改變當前行的設(shè)置:

myBindingManagerBaseParent.Position = 10;

BindingManagerBase.Position屬性的變化就會引起B(yǎng)indingManagerBase當前行的變化,也就是跟這個數(shù)據(jù)源綁定的DataGrid的當前行的變化,簡單綁定控件的顯示內(nèi)容也就隨之改變了。

BindingManagerBase的DataSource可以是DataSet,DataSet中可以有多個DataTable,這些DataTable可以通過DataRelaton(關(guān)系)聯(lián)系在一起,形成父表/子表的關(guān)系。比如,還是上面舉過的例子,一個DataGrid顯示Customer表,同時還想要有一個DataGrid來顯示當前Customer所有的order。這樣我們就會需要兩個BindingManagerBase了,一個BindingManagerBase對應Customer表,另一個BindingManagerBase對應order表,而且這個order表還要考慮到同Customer表的關(guān)系。

對應Customer的BindingManagerBase上面我們已經(jīng)建立好了,下面我們來建立對應order的BindingManagerBase:

首先我們要建立Customer表和order表之間的關(guān)系myRelation:

DataColumn ParentColumn = myDataSet.Tables["customers"].Columns["customerid"]; 
//要建立關(guān)系的父表的列,相當于主鍵 
DataColumn ChildColumn = myDataSet.Tables["orders"].Columns["customerid"]; 
//要建立關(guān)系的子表的列,相當于外鍵 
DataRelation myRelation = new DataRelation("myRelation",ParentColumn,ChildColumn,false); 
//根據(jù)父表,子表的相關(guān)列建立關(guān)系

然后,通過關(guān)系,建立對應order表的BindingManagerBase:

myBindingManagerBaseChild = this.BindingContext[myDataSet,"customers.myRelation"]; //這個數(shù)據(jù)源將解析為一個父表中的客戶對應的所有的order

這樣,當對應Customer的BindingManagerBase的當前行改變時,對應order的BindingManagerBase也將跟著變化,他們之間的關(guān)系是由myRelation決定的

◆ 在程序中訪問DataGrid中的內(nèi)容

DataTable中有數(shù)據(jù)行DataRow,而在DataGrid中沒有行這個對象,這讓人感到很不習慣,也覺得不夠自然。在DataTable中,一張表的層次結(jié)構(gòu)很清楚,DataTable.Rows屬性可以得到這張表所包含的所有行的行集,通過行集的索引DataRowCollection[index]就可以得到具體的一個DataRow,數(shù)據(jù)行的索引DataRow[index]又可以得到這一行的具體某一列的內(nèi)容。

而DataGrid中就沒有這么方便了,DataGrid只有兩個屬性可用,DataGrid.CurrentCell 屬性,此屬性返回一個DataGridCell類型的結(jié)構(gòu),DataGridCell結(jié)構(gòu)指明此Cell所在的行號和列號。還有一個DataGrid.Item 屬性,此屬性有兩個重載:

public object this[DataGridCell] //獲取或設(shè)置指定的 DataGridCell 的值

public object this[int, int] //獲取或設(shè)置位于指定行和列的單元格的值

可見,DataGrid中訪問都是針對某個Cell進行的。經(jīng)常的,我們需要從當前的Cell獲得此Cell所對應的DataRow,比如界面中可能先選中DataGrid的某一行,或者某一個Cell,然后點擊一個按鈕,彈出一個新的窗口,窗口中顯示這一行的所有單元的內(nèi)容,并允許修改單元的值,***保存關(guān)閉窗口。這就需要從當前的DataGrid所在的單元找到其所對應的DataTable所在的行和列。

而DataGrid中顯示的數(shù)據(jù)可能經(jīng)過DataView的DataView.RowFilter屬性、DataView.RowStateFilter屬性的過濾,還可能經(jīng)過DataGrid本身根據(jù)各個列的正向和反向排序,所以DataGrid的CurrentRowIndex屬性所指示的行索引跟其對應的DataTable的行索引有很大的機會是不一樣的,不能夠根據(jù)DataGrid的CurrentRowIndex去獲取其對應的DataTable的行。

這時BindingManagerBase又將發(fā)揮作用了,我們可以先建立一個對應此DataGrid綁定的數(shù)據(jù)源的BindingManagerBase,這樣這個BindingManagerBase就可以管理這個數(shù)據(jù)源。

//設(shè)置DataGrid的數(shù)據(jù)源 
dataGrid1.DataSource = myDataSet; 
dataGrid1.DataMember = "customers"; 
//建立同DataGrid同樣數(shù)據(jù)源的BindingManagerBase 
BindingManagerBase myBindingManagerBaseParent = 
this.BindingContext[myDataSet,"customers"];

一旦建立了這個BindingManagerBase,就可以通過BindingManagerBase的當前行的屬性來獲取當前數(shù)據(jù)源的記錄:

//BindingManagerBase的Current返回數(shù)據(jù)源的對象,對于綁定到DataView的數(shù)據(jù)源,需要將此對象顯式

//的轉(zhuǎn)換為 DataRowView類型

DataRowView myDataRowView =(DataRowView) myBindingManagerBaseParent.Current

這樣,我們就可以從當前的Cell得到此Cell所在的DataRowView,DataRowView又可以通過DataRowView.Row屬性及其方便的得到DataRow。

如果還要進一步,想要得到此Cell所對應的DataTable的具體單元,就是不光要得到DataRow,還要知道這個Cell所對應的列。

這又分兩種情況:

一是DataGrid未使用TableStyles來設(shè)置DataGrid要顯示的列和格式,數(shù)據(jù)源DataView的所有列都將按照DataView本身的順序顯示出來,這樣可以直接取得對應的列索引:

//獲取當前DataGrid單元的列索引,這個索引跟DataTable的索引是一樣的
Int ColumnNumber = DataGrid.CurrentCell.ColumnNumber;

另一種情況是DataGrid使用了TableStyles來設(shè)置DataGrid要顯示的列和格式,這樣DataGrid單元的列索引跟DataTable的索引就可能是不一樣的了,這就要用DataGrid的TableStyles了:

Int ColumnNumberDataGrid = DataGrid.CurrentCell.ColumnNumber; 
//獲取當前DataGrid單元的列索引 
Int ColumnNumberDataTable = 
DataGrid.TableStyles[0].GridColumnStyles[ColumnNumberDataGrid].MappingName

以上就是ADO.NET中容易混淆的概念是什么,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

本文標題:ADO.NET中容易混淆的概念是什么
網(wǎng)頁URL:http://muchs.cn/article26/gdiccg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、品牌網(wǎng)站制作用戶體驗、網(wǎng)站維護品牌網(wǎng)站設(shè)計、微信公眾號

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計