DataTable是一個使用非常多的類,記得我在剛剛開始學習.Net的時候就已經了解並用過這個類,但如今再來看看,才發現這個類非常之復雜,復雜表現在哪些地方呢?主要是這個類與其他很多類都有關聯,也就是說,你要玩透DataTable這個類,你必須要了解很多其他的類。
DataTable是一個很古老的類,再往前不清楚,但是.Net2.0就肯定有了。主要用於數據的封裝與存儲等等。這個類,你要是在公司里工作,必定會用到,無論是維護舊系統或是使用一些老框架都會用到,必須要熟悉常用的操作。
下面給出一些DataTable的常用操作,
1、查找Select
static void Main(string[] args) { DataTable dt = new DataTable(); 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", "黃忠"); DataRow[] drArr = dt.Select("Id > 1 and Name <> '關羽'" ,"Id desc"); //條件支持and or like與SQL語句類似 //DataRow[] drArr2 = dt.Select("Name like '關%'", "Id desc"); //like示例 foreach(DataRow dr in drArr) { Console.WriteLine(dr["Name"]); //輸出 黃忠 趙雲 張飛 } Console.ReadKey(); }
2、排序、聚合:
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、自增列
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。
示例,假設在DataSet中我設置了一個int類型,但是在顯示的時候,我想讓為0的地方顯示為空白該怎么實現呢?
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(); }
這樣本來顯示為0的地方就實現為空白了: