在項目中,經常會遇到這樣的問題。用SQL從數據庫中選出需要的數據存入DataTable之后,需要進行一定的處理之后,才可以用來顯示在頁面上。
之前對這些問題,都是遇到一個就百度一個,沒有系統的處理這些問題,今天就寫個文檔來處理一下這個問題
先來幾個簡單的嘍。
添加列和行:
(既然是整理, 那就寫全一點吧,三個方法)
#region 方法一: DataTable tblDatas =new DataTable("Datas"); //表名 DataColumn dc =null; dc = tblDatas.Columns.Add("ID", Type.GetType("System.Int32")); dc.AutoIncrement =true;//自動增加 dc.AutoIncrementSeed =1;//起始為1 dc.AutoIncrementStep =1;//步長為1 dc.AllowDBNull =false; //不允許為空 dc = tblDatas.Columns.Add("Product", Type.GetType("System.String")); dc = tblDatas.Columns.Add("Version", Type.GetType("System.String")); dc = tblDatas.Columns.Add("Description", Type.GetType("System.String")); // DataRow newRow; newRow = tblDatas.NewRow(); newRow["Product"] ="這個地方是單元格的值"; newRow["Version"] ="2.0"; newRow["Description"] ="這個地方是單元格的值"; tblDatas.Rows.Add(newRow); newRow = tblDatas.NewRow(); newRow["Product"] ="這個地方是單元格的值"; newRow["Version"] ="3.0"; newRow["Description"] ="這個地方是單元格的值"; tblDatas.Rows.Add(newRow); #endregion
看完一個方法,也許會問 dc = tblDatas.Columns.Add("Product", Type.GetType("System.String")); 為什么要用 dc= 這個東西啊 tblDatas.Columns.Add("Product", Type.GetType("System.String")); 直接用之個也可以啊。確實,這樣也是可以的,用 dc= 是為了方便給這個列設置屬性。比如,我要設置這個列不能為空 我就可以 dc.AllowDBNull =false; 就像第一列一樣
#region 方法二: DataTable tblDatas =new DataTable("Datas"); tblDatas.Columns.Add("ID", Type.GetType("System.Int32")); tblDatas.Columns[0].AutoIncrement =true; tblDatas.Columns[0].AutoIncrementSeed =1; tblDatas.Columns[0].AutoIncrementStep =1; tblDatas.Columns.Add("Product", Type.GetType("System.String")); tblDatas.Columns.Add("Version", Type.GetType("System.String")); tblDatas.Columns.Add("Description", Type.GetType("System.String")); tblDatas.Rows.Add(newobject[] { null, "a", "b", "c" }); tblDatas.Rows.Add(newobject[] { null, "a", "b", "c" }); tblDatas.Rows.Add(newobject[] { null, "a", "b", "c" }); tblDatas.Rows.Add(newobject[] { null, "a", "b", "c" }); tblDatas.Rows.Add(newobject[] { null, "a", "b", "c" }); #endregion
這個方法沒有使用到 dc= 所用設置屬性的時候 就要tblDatas.Columns[0].AutoIncrement =true; 這樣去設置, 個人覺得比較麻煩。這個就是給Table的列賦值的時候,一次把一行的數據按照順序全加進去。而第一個方法就是一列一列的輔助,那樣的話 就比較麻煩。dt.Rows.Add(new object[] { null, "Tang", "W", "25", "50" });這里第一個值賦值的是NULL 是因為這是一個自動添加列 所以要賦值為NULL
#region 方法三: DataTable table =new DataTable(); //創建table的第一列 DataColumn priceColumn =new DataColumn(); priceColumn.DataType = System.Type.GetType("System.Decimal");//該列的數據類型 priceColumn.ColumnName ="price";//該列得名稱 priceColumn.DefaultValue =50;//該列得默認值 // 創建table的第二列 DataColumn taxColumn =new DataColumn(); taxColumn.DataType = System.Type.GetType("System.Decimal"); taxColumn.ColumnName ="tax";//列名 taxColumn.Expression ="price * 0.0862";//設置該列得表達式,用於計算列中的值或創建聚合列 // 創建table的第三列 DataColumn totalColumn =new DataColumn(); totalColumn.DataType = System.Type.GetType("System.Decimal"); totalColumn.ColumnName ="total"; totalColumn.Expression ="price + tax";//該列的表達式,是第一列和第二列值得和 // 將所有的列添加到table上 table.Columns.Add(priceColumn); table.Columns.Add(taxColumn); table.Columns.Add(totalColumn); //創建一行 DataRow row = table.NewRow(); table.Rows.Add(row);//將此行添加到table中
這個方法相對來說用的比較少,但是也很有用,比如 我從DB 中選取到一個字段,當我綁定到頁面的時候,我添加幾個字段(百分比,總和)就可以在Table中添加一個列 totalColumn.Expression ="price + tax"; 用這種方法去計算。
操作Table中的數據當然會用到 Select 方法了。下面就說說 這個方法。
Select方法
首先select這個方法,一共有四個重載的函數
1:Select()
2:Select(string filterExpression)
3:Select(string filterExpression, string sort)
4:Select(string filterExpression,string sort, DataViewRowState record States)。
說白了,用這個方法只需要了解這幾個參數是什么意思 就沒有什么大問題了。那就一個一個來
1:select()
這個沒參數,就沒得說了。就是把DataTable中的數據都選出來。但要注意的是,select方法選出的都是DataRow 對象的數組。這個沒有參數的使用的相對來說比較少。
2:Select(string filterExpression)
這個filterExpression 就是一個表達式。這個就要研究一下了。表達式支持“and, Like, or”
比如
Select("id>='3' and name='hello'"); (選出id這個字段大於等於3並且name 等於“hello”的數據)
Select("id>='3' or id='1'"); (選出id大於等於3 或者id等於1的數據)
Select("name like '%hello%'");(選出name用hello的數據)
3:Select(string filterExpression, string sort)
這個方法中的sort是排序的意思。就是你用表達式選出DataRow的數據之后,可以用sort這個參數來對這些數據進行排序。
就是在第二個方法的基礎上再加一個排序的功能嘍 Select("id>='3' or id='1'","id desc"); 按照id 降續排列。
4:Select(string filterExpression,string sort, DataViewRowState record States)。
這個有加了一個參數,叫行狀態。這個什么東西啊,MSDN 是這樣說的https://msdn.microsoft.com/zh-cn/library/system.data.dataviewrowstate.aspx,DataViewRowState 是一個枚舉類型(有興趣的可以看看)
成員名稱 |
說明 | |
|---|---|---|
| Added |
一個新行。 |
|
| CurrentRows |
包括未更改行、新行和已修改行的當前行。默認情況下,DataViewRowState 項設置當前行。 |
|
| Deleted |
已刪除的行。 |
|
| ModifiedCurrent |
已修改的原始數據的當前版本(請參見 ModifiedOriginal)。 |
|
| ModifiedOriginal |
已修改的數據的原始版本。(盡管此數據已被修改,它仍作為 ModifiedCurrent 可用)。 |
|
| None |
無。 |
|
| OriginalRows |
包括未更改行和已刪除行的原始行。 |
|
| Unchanged |
未更改的行。 |
總結一下這個Select方法,你可能會發現,這個filterExpression的參數是查詢的限定式。相當於SQL查詢語言中的WHERE語句,其語法符合SQL語法 。
Select方法是不區分大小寫的(字段名不區分),如果需要區分大小寫,需要將DataTable的caseSensitive屬性設為true。
Select方法的返回的是包含查詢到的數據的DataRow數組,但是這個DataRow只是被查詢的DataTable的一個映射,所以DataRow是隨着DataTable的行變化而變化的。例如,DataTable的行都被刪除了,那么DataRow中的數據同樣被刪除了(即便是先Select,再刪除的)
所以,要想把返回的DataRow放進數據顯示控件中,需要將其放入另一個DataTable中,如果直接放入原DataTable或將原DataTable的行全部清除再放入查詢所得的數據都是不行的,程序會顯示錯誤,錯誤提示是“表中已有此行”。就要把選出來的DataRow放在新建的表中。
另外,在一個新表中插入行,不能直接用DataTable.Rows.Add(DataRow)的方式,因為這樣是插入一個新表,也就是DataRow是空的(簡單說就是沒有列)。要用導入行的方式,DataTable.ImportRow(DataRow)。當然,前提是這個新表要有與原數據表一樣的結構。
那么問題就來了,怎么創建一個與原數據表一樣結構的表,DataTable中有兩個方法DataTable.Clone() ;DataTable.Copy();
DataTable.Clone() 這個只會克隆表的結構(也就是列)
DataTable.Copy() 這個不僅會有表的結構還有表中的數據。
所以呢,就很明顯了,DataTable dtClone = dt.Clone() ; 先創建一個與原數據表一樣結構的表,然后再講select出來的數據添加到表中,記得要用DataTable.ImportRow(DataRow)。這個方法。
