DataTable 表示一個內(nèi)存內(nèi)關(guān)系數(shù)據(jù)的表,可以獨立創(chuàng)建和使用,也可以由其他 .NET Framework 對象使用,最常見的情況是作為 DataSet 的成員使用。
DataTable 對象可通過使用 DataTable 構(gòu)造函數(shù)來創(chuàng)建,或者可通過將構(gòu)造函數(shù)參數(shù)傳遞到 DataSet 的 Tables 屬性的 Add 方法(它是一個 DataTableCollection)來創(chuàng)建。
DataTable 對象可通過使用 DataAdapter 對象的 Fill 方法或 FillSchema 方法在 DataSet 內(nèi)創(chuàng)建,或者可使用 DataSet 的 ReadXml、ReadXmlSchema 或 InferXmlSchema 方法從預(yù)定義的或推斷的 XML 架構(gòu)中創(chuàng)建。請注意,將一個 DataTable 作為成員添加到一個 DataSet 的 Tables 集合中后,不能再將其添加到任何其他 DataSet 的表集合中。
最初創(chuàng)建 DataTable 時,它是沒有架構(gòu)(結(jié)構(gòu))的。要定義表的架構(gòu),必須創(chuàng)建 DataColumn 對象并將其添加到表的 Columns 集合中。您也可以為表定義主鍵列,并且可以創(chuàng)建 Constraint 對象并將其添加到表的 Constraints 集合中。在為 DataTable 定義了架構(gòu)之后,可通過將 DataRow 對象添加到表的 Rows 集合中來將數(shù)據(jù)行添加到表。
創(chuàng)建 DataTable 時,不需要為 TableName 屬性提供值,您可以在其他時間指定屬性,或者將其保留為空。但是,在將一個沒有 TableName 值的表添加到 DataSet 中時,該表會得到一個從“Table”(表示 Table0)開始遞增的默認名稱 TableN。
[C#]
DataTable workTable = new DataTable("Customers");
DataSet custDS = new DataSet();
DataTable custTable = custDS.Tables.Add("CustTable");
DataTable 包含了由表的 Columns 屬性引用的 DataColumn 對象的集合。這個列的集合與任何約束一起定義表的架構(gòu)或結(jié)構(gòu)。
通過使用 DataColumn 構(gòu)造函數(shù),或者通過調(diào)用表的 Columns 屬性的 Add 方法(它是一個 DataColumnCollection),可在表內(nèi)創(chuàng)建 DataColumn 對象。Add 方法將接受可選的 ColumnName、DataType 和 Expression 參數(shù),并將創(chuàng)建新的 DataColumn 作為集合的成員。它也會接受現(xiàn)有的 DataColumn 對象并會將其添加到集合中,并會根據(jù)請求返回對所添加的 DataColumn 的引用。由于 DataTable 對象對任何數(shù)據(jù)源都不是特定的,所以在指定 DataColumn 的數(shù)據(jù)類型時會使用 .NET Framework 類型。
DataTable workTable = new DataTable("Customers");
DataColumn workCol = workTable.Columns.Add("CustID", typeof(Int32));
workCol.AllowDBNull = false;
workCol.Unique = true;
workTable.Columns.Add("CustLName", typeof(String));
workTable.Columns.Add("CustFName", typeof(String));
workTable.Columns.Add("Purchases", typeof(Double));
請注意,示例中用于 CustID 列的屬性設(shè)置為不允許 DBNull 值并將值約束為唯一。但是,如果您將 CustID 列定義為表的主鍵列,AllowDBNull 屬性就會自動設(shè)置為 false,并且 Unique 屬性會自動設(shè)置為 true。有關(guān)更多信息,請參見為表定義主鍵。
在創(chuàng)建 DataTable 并使用列和約束定義其結(jié)構(gòu)之后,您可以將新的數(shù)據(jù)行添加到表中。要添加新行,可將一個新變量聲明為 DataRow 類型。調(diào)用 NewRow 方法時,將返回新的 DataRow 對象。然后,DataTable 會根據(jù)表的結(jié)構(gòu)按 DataColumnCollection 的定義創(chuàng)建 DataRow 對象。
以下示例向新建的 Customers 表中添加了十行。
[C#]
DataRow workRow;
for (int i = 0; i <= 9; i++)
{
workRow = workTable.NewRow();
workRow[0] = i;
workRow[1] = "CustName" + i.ToString();
workTable.Rows.Add(workRow);
}
::您也可以通過傳入值的數(shù)組(類型化為 Object),調(diào)用 Add 方法來添加新行,如下例所示。
[C#]
workTable.Rows.Add(new Object[] {1, "Smith"});
[C#]
workRow["CustLName"] = "Smith";
workRow[1] = "Smith";
workTable.Rows.Add(workRow);
------------------------------------------------------------
可以使用 DataTable 的 Rows 和 Columns 集合來訪問 DataTable 中的內(nèi)容。也可以根據(jù)包括搜索標(biāo)準(zhǔn)、排序順序和行狀態(tài)等特定標(biāo)準(zhǔn),
使用 DataTable.Select 方法返回 DataTable 中數(shù)據(jù)的子集。此外,用主鍵值搜索特定行時,還可使用 DataRowCollection 的 Find
方法。
DataTable 對象的 Select 方法返回一組與指定條件匹配的 DataRow 對象。Select 采用篩選表達式、排序表達式和 DataViewRowState
的可選參數(shù)。篩選表達式根據(jù) DataColumn 值(例如 LastName = 'Smith'
。排序表達式遵循用于為列排序的標(biāo)準(zhǔn) SQL 約定,例如
LastName ASC, FirstName ASC
。有關(guān)編寫表達式的規(guī)則,請參見 DataColumn 類的 Expression 屬性。
[C#]
DataRow[] currRows = workTable.Select(null, null, DataViewRowState.CurrentRows);
if (currRows.Length < 1 )
Console.WriteLine("No Current Rows Found");
else
{
foreach (DataColumn myCol in workTable.Columns)
Console.Write("\t{0}", myCol.ColumnName);
Console.WriteLine("\tRowState");
foreach (DataRow myRow in currRows)
{
foreach (DataColumn myCol in workTable.Columns)
Console.Write("\t{0}", myRow[myCol]);
Console.WriteLine("\t" + myRow.RowState);
}
}
------------------------------------------------------
當(dāng)您在 DataRow 中更改列值時,所做更改會立即置于行的 Current 狀態(tài)中。然后,RowState 會設(shè)置為 Modified,并使用 DataRow 的
AcceptChanges 或 RejectChanges 方法來接受或拒絕所做更改。DataRow 還提供了三種可用于在編輯行時將行的狀態(tài)掛起的方法。
這些方法是 BeginEdit、EndEdit 和 CancelEdit。
當(dāng)您直接在 DataRow 中修改列值時,DataRow 會使用 Current、Default 和 Original 行版本來管理列值。除這些行版本以外,
BeginEdit、EndEdit 和 CancelEdit 方法還使用第四個行版本:Proposed。有關(guān)行版本的更多信息,請參見行狀態(tài)與行版本。
在執(zhí)行編輯操作(通過調(diào)用 BeginEdit 開始,并且通過使用 EndEdit 或 CancelEdit 或者通過調(diào)用 AcceptChanges 或 RejectChanges 結(jié)束)
的過程中,Proposed 行版本會存在。
在編輯操作過程中,您可以通過計算 DataTable 的 ColumnChanged 事件中的 ProposedValue 來將驗證邏輯應(yīng)用于各列。ColumnChanged
事件保存 DataColumnChangeEventArgs,可保持對正在更改的列和 ProposedValue 的引用。計算了建議值后,可以對其進行修改或取消編輯。
編輯結(jié)束時,行從 Proposed 狀態(tài)中移出。
您可以通過調(diào)用 EndEdit 來確認編輯,也可以通過調(diào)用 CancelEdit 來取消編輯。請注意,盡管 EndEdit 確實已確認您所做的編輯,但在調(diào)用
AcceptChanges 之前,DataSet 并沒有實際接受更改。另外請注意,如果在 EndEdit 或 CancelEdit 編輯結(jié)束之前調(diào)用 AcceptChanges,
編輯將會終止,并接受 Current 和 Original 行版本的 Proposed 行值。調(diào)用 RejectChanges 會以同樣的方式結(jié)束編輯,并放棄 Current
和 Proposed 行版本。在調(diào)用 AcceptChanges 或 RejectChanges 之后調(diào)用 EndEdit 或 CancelEdit 不會起作用,因為編輯已經(jīng)結(jié)束。
[C#]
DataTable workTable = new DataTable();
workTable.Columns.Add("LastName", typeof(String));
workTable.ColumnChanged += new DataColumnChangeEventHandler(OnColumnChanged);
DataRow workRow = workTable.NewRow();
workRow[0] = "Smith";
workTable.Rows.Add(workRow);
workRow.BeginEdit();
// Causes the ColumnChanged event to write a message and cancel the edit.
workRow[0] = "";
workRow.EndEdit();
// Displays "Smith, New".
Console.WriteLine("{0}, {1}", workRow[0], workRow.RowState);
protected static void OnColumnChanged(Object sender, DataColumnChangeEventArgs args)
{
if (args.Column.ColumnName == "LastName")
if (args.ProposedValue.ToString() == "")
{
Console.WriteLine("Last Name cannot be blank. Edit canceled.");
args.Row.CancelEdit();
}
}