一、DataTable簡介
(1)構造函數
名稱 | 說明 |
DataTable() | 不帶參數初始化DataTable 類的新實例 |
DataTable(string tableName) | 用指定的表名初始化DataTable 類的新實例 |
DataTable(string tableName, string tableNamespace) | 用指定的表名和命名空間初始化DataTable類的新實例 |
(2)常用屬性
名稱 | 說明 |
CaseSensitive | 指示表中的字符串比較是否區分大小寫 |
ChildRelations | 獲取此DataTable 的子關系的集合 |
Columns | 獲取屬於該表的列的集合 |
Constraints | 獲取由該表維護的約束的集合 |
DataSet | 獲取此表所屬的DataSet |
DefaultView | 獲取可能包括篩選視圖或游標位置的表的自定義視圖 |
HasErrors | 獲取一個值,該值指示該表所屬的DataSet 的任何表的任何行中是否有錯誤 |
MinimumCapacity | 獲取或設置該表最初的起始大小。該表中行的最初起始大小。默認值為50 |
Rows | 獲取屬於該表的行的集合 |
TableName | 獲取或設置DataTable的名稱 |
(3)常用方法
名稱 | 說明 |
AcceptChanges() | 提交自上次調用AcceptChanges() 以來對該表進行的所有更改 |
BeginInit() | 開始初始化在窗體上使用或由另一個組件使用的DataTable。初始化發生在運行時 |
Clear() | 清除所有數據的DataTable |
Clone() | 克隆DataTable 的結構,包括所有DataTable 架構和約束 |
EndInit() | 結束在窗體上使用或由另一個組件使用的DataTable 的初始化。初始化發生在運行時 |
ImportRow(DataRow row) | 將DataRow 復制到DataTable 中,保留任何屬性設置以及初始值和當前值 |
Merge(DataTable table) | 將指定的DataTable 與當前的DataTable 合並 |
NewRow() | 創建與該表具有相同架構的新DataRow |
二、DataTable使用技巧
(1)查找Select

using System; using System.Data; using System.Text; namespace ConsoleApp { class Program { static void Main(string[] args) { DataTable dt = new DataTable("temp"); dt.Columns.Add("Id"); //添加列 dt.Columns.Add("Name"); dt.Rows.Add("1", "劉備"); //添加行 dt.Rows.Add("2", "關羽"); dt.Rows.Add("3", "張飛"); dt.Rows.Add("4", "趙雲"); dt.Rows.Add("5", "黃忠"); SelectFun(dt); Console.ReadKey(); } #region 遍歷范例 /// <summary> /// 遍歷方式一 /// </summary> /// <param name="dt"></param> static void TraversalFun1(DataTable dt) { for (int i = 0; i < dt.Rows.Count; i++) { Console.WriteLine("編號:{0};名稱:{1}", dt.Rows[i]["Id"].ToString(), dt.Rows[i]["Name"].ToString()); } } /// <summary> /// 遍歷方式二 /// </summary> /// <param name="dt"></param> static void TraversalFun2(DataTable dt) { foreach (DataRow myRow in dt.Rows) { Console.WriteLine("編號:{0};名稱:{1}", myRow[0].ToString(), myRow[1].ToString()); } } /// <summary> /// 遍歷方式三 /// </summary> /// <param name="dt"></param> static void TraversalFun3(DataTable dt) { foreach (DataRow dr in dt.Rows) { Console.WriteLine("編號:{0};名稱:{1}", dr["Id"].ToString(), dr["Name"].ToString()); } } /// <summary> /// 遍歷方式四 /// </summary> /// <param name="dt"></param> static void TraversalFun4(DataTable dt) { StringBuilder msg = new StringBuilder(); foreach (DataRow dr in dt.Rows) { msg.Clear(); foreach (DataColumn dc in dt.Columns) { msg.AppendFormat("{0}:{1};", dc.ColumnName, dr[dc.ColumnName]); } Console.WriteLine(msg.ToString()); } } #endregion #region 查找范例 static void SelectFun(DataTable dt) { //條件查詢 Console.WriteLine("條件查詢示例語句:Id > 1 and Name <> '關羽'"); Display(dt.Select("Id > 1 and Name <> '關羽'", "Id desc")); //like示例 Console.WriteLine("like示例語句:Name like '關%"); Display(dt.Select("Name like '關%'", "Id desc")); } static void Display(DataRow[] drArr) { foreach (DataRow dr in drArr) { Console.WriteLine(dr["Name"]); } } #endregion } }
(2)排序、聚合

using System; using System.Data; namespace ConsoleApp { class Program { static void Main(string[] args) { DataTable dt = new DataTable(); dt.Columns.Add("Id"); dt.Columns.Add("Name"); dt.Columns.Add("Age", typeof(Int32)); //注意要計算平均值要設置列類型為數字 dt.Rows.Add("1", "劉備", 31); dt.Rows.Add("2", "關羽", 29); dt.Rows.Add("3", "張飛", 28); dt.Rows.Add("4", "趙雲", 27); dt.Rows.Add("5", "黃忠", 50); dt.DefaultView.Sort = "Age DESC"; //排序 dt = dt.DefaultView.ToTable(); foreach (DataRow dr in dt.Rows) { Console.WriteLine(dr["Name"]); } object obj = dt.Compute("Count(Id)", "Age>26"); //輸出3 查詢年齡大於26的人數 Console.WriteLine(obj.ToString()); object obj2 = dt.Compute("Avg(Age)", "true"); //輸出33 查詢所有人的平均年齡(要設置列為整型,否則不能計算) Console.WriteLine(obj2.ToString()); object obj3 = dt.Compute("Sum(Age)", "true"); //輸出165 Console.WriteLine(obj3.ToString()); Console.ReadKey(); } } }
(3)自增列

using System; using System.Data; namespace ConsoleApp { class Program { static void Main(string[] args) { DataTable dt = new DataTable(); DataColumn dc = dt.Columns.Add("Id", Type.GetType("System.Int32")); dc.AutoIncrement = true; //自動增加 dc.AutoIncrementSeed = 1; //起始為1 dc.AutoIncrementStep = 1; //步長為1 dc.AllowDBNull = false; //不允許為空 dt.Columns.Add("Name", Type.GetType("System.String")); dt.Columns.Add("Age", typeof(Int32)); //注意要計算平均值要設置列類型為數字 dt.Rows.Add(null, "劉備", 31); //注意這次添加不用在手輸Id了,但是要給個null dt.Rows.Add(null, "關羽", 29); dt.Rows.Add(null, "張飛", 28); dt.Rows.Add(null, "趙雲", 27); dt.Rows.Add(null, "黃忠", 50); foreach (DataRow dr in dt.Rows) { Console.WriteLine(dr["Id"]); //輸出1 2 3 4 5 } Console.ReadKey(); } } }
(4)System.DBNull
null在.Net中表示無效的對象引用。 即空對象。
DBNull是一個類(System.DBNull)。這個類直接繼承於Object,它只有繼承下來的屬性與方法,只有一個自己的字段value。表示它自己。指數據庫中數據為空(NULL)時,在.Net中的值。DBNull.Value表示一個對象在數據庫中的值為空,或者說未初始化,DBNull.Value對象是指向有效的對象。
但是為什么 DBNull 可以表示數據庫中的字符串,數字,或日期呢?原因是.Net儲存這些數據的類(DataRow等)都是以 object 的形式來儲存數據的。
對於 DataRow , 它的 row["column"] 返回的值永遠不為null , 要么就是具體的為column的類型的值。要么就是DBNull 。 所以 row[column].ToString() 這個寫法永遠不會在ToString那里發生NullReferenceException,但有可能拋下標越界的異常。
DBNull 實現了 IConvertible 。 但是,除了 ToString 是正常的外,其他的ToXXX都會拋出不能轉換的錯誤。
在 IDbCommand(OleDbCommand,SqlCommand...) 的ExecuteScalar的返回值中,情況可以這樣分析:
SELECT 1 --這樣返回的object是1。
SELECT null --這樣返回的是DBNull.Value。
eg:假設在DataSet中我設置了一個int類型,但是在顯示的時候,我想讓為0的地方顯示為空白該怎么實現呢?

using System; using System.Data; namespace ConsoleApp { class Program { static void Main(string[] args) { DataTable dt = new DataTable(); dt.Columns.Add("Name", typeof(String)); dt.Columns.Add("Age", typeof(Int32)); dt.Rows.Add("撼地神牛", 0); dt.Rows.Add("劉備", 21); for (int i = 0; i < dt.Rows.Count; i++) { if (dt.Rows[i]["Age"].ToString() == "0") { //dt.Rows[i]["Age"] = null; 這樣寫會提示如下錯誤:不能將 Column“Age”設置為 null。請改用 DBNull。 dt.Rows[i]["Age"] = DBNull.Value; } Console.WriteLine(dt.Rows[i]["Name"] + ":" + dt.Rows[i]["Age"]); } Console.ReadKey(); } } }