C#中DataTable排序、檢索、合並等操作實例


 

轉載引用至:http://www.jb51.net/article/49222.htm
 
 

一、排序
1.獲取DataTable的默認視圖
2.對視圖設置排序表達式
3.用排序后的視圖導出的新DataTable替換就DataTable(Asc升序可省略,多列排序用","隔開)
1)、重生法

復制代碼代碼如下:
dstaset.Tables.Add(dt)
dataset.Tables(0).DefaultView.Sort = "id desc"

2)、直接法
復制代碼代碼如下:
dv = New DataView(dt)
dv.Sort = "id desc"
dt = dv.ToTable();

3)、間接法
復制代碼代碼如下:
dv = New DataView(ds.Tables[0])
dv.Sort = "id desc"
dt = dv.ToTable();


二、檢索

設置查詢字符串
使用Select方法獲取到所有滿足條件的數據行對象數組 (多項查詢條件間,用and隔開)
復制代碼代碼如下:
DataRow[] matches = dt.Select("id<'003' and name='名字11'");
string strName = matches[0]["name"].ToString();

 

三、合並

假定有2個DataTable:Dt1 , Dt2。表結構一樣
將Dt2接在Dt1后可采用此方法

復制代碼代碼如下:
dt1.Merge(dt2);

 


四、在DataTable中查詢應該注意的問題

完成一個查詢,返回一個DataTable后,很多時候都想在查詢結果中繼續搜索。這時可以使用DataTable.Select方法對結果進行再查詢
Select方法有4個重載,我們經常用到的就是DataTable.Select(String)
這個String的參數是查詢的限定式。相當於SQL查詢語言中的WHERE語句(不含WHERE),其語法符合SQL語言語法。
Select方法的返回的是包含查詢到的數據的DataRow,但是這個DataRow只是被查詢的DataTable的一個映射,所以DataRow是隨着DataTable的行變化而變化的。例如,DataTable的行都被刪除了,那么DataRow中的數據同樣被刪除了(即便是先Select,再刪除的)
所以,要想把返回的DataRow放進數據顯示控件中,需要將其放入另一個DataTable中,如果直接放入原DataTable或將原DataTable的行全部清除再放入查詢所得的數據都是不行的,程序會顯示錯誤,錯誤提示是“表中已有此行”。
另外,在一個新表中插入行,不能直接用DataTable.Rows.Add(DataRow)的方式,因為這樣是插入一個新表,也就是DataRow是空的。要用導入行的方式,DataTable.ImportRow(DataRow)。當然,前提是這個新表要有與原數據表一樣的結構。

復制代碼代碼如下:
Public Function SDEResearch(ByVal InputDT As DataTable, ByVal SearchStr As String) As DataTable

 

'用來存儲再查詢后的數據表 
Dim ReSearchDT As DataTable = InputDT.Clone() '保證有與源數據表相同的表結構

'用來存儲查詢后返回的datarow數組 
Dim ReSearchDR() As DataRow = Nothing

Try 
ReSearchDR = InputDT.Select("NAME LIKE '%" + SearchStr + "%'") '只是從數據表中映射出來datarow(),所以不能刪除原表中的行 
Catch ex As Exception 
Return Nothing 
End Try

For i As Int16 = 0 To ReSearchDR.Length - 1 
ReSearchDT.ImportRow(ReSearchDR(i)) 
Next

Return ReSearchDT 
End Function

 

附:篩選DataTable數據的方法

對DataTable進行過濾篩選的一些方法Select,dataview
當你從數據庫里取出一些數據,然后要對數據進行整合,你很容易就會想到:

復制代碼代碼如下:
DataTable dt = new DataTable();//假設dt是由"SELECT C1,C2,C3 FROM T1"查詢出來的結果 
for (int i = 0; i < dt.Rows.Count; i++) 

    if (dt.Rows[i]["C1"].ToString() == "abc")//查詢條件 
    { 
        //進行操作 
    } 
}

但這種做法用一兩次還好說,用多了就累了。那有沒有更好的方法呢?記得LinQ是可以直接對DataTable進行查詢操作的,那在.Net Framework 2.0里,有沒有類似的方法呢?答案是肯定的,就是dt.Select(),上面的操作可以改成這樣:
復制代碼代碼如下:
DataRow[] drArr = dt.Select("C1='abc'");//查詢

還可以這樣操作:
復制代碼代碼如下:
DataRow[] drArr = dt.Select("C1 LIKE 'abc%'");//模糊查詢 
DataRow[] drArr = dt.Select("'abc' LIKE C1 + '%'", "C2 DESC");//另一種模糊查詢的方法 
DataRow[] drArr = dt.Select("C1='abc'", "C2 DESC");//排序

問題又來了,如果要把DataRow賦值給新的DataTable,怎么賦值呢?你可能會想到:
復制代碼代碼如下:
DataTable dtNew = dt.Clone(); 
for (int i = 0; i < drArr.Length; i++) 

    dtNew.Rows.Add(drArr[i]); 
}

但這樣程序就會出錯,說該DataRow是屬於其他DataTable的,那要怎么做呢?很簡單,這樣就可以解決了:
復制代碼代碼如下:
DataTable dtNew = dt.Clone(); 
for (int i = 0; i < drArr.Length; i++) 

    dtNew.ImportRow(drArr[i]); 
}

這樣就完成了。
3.5里的DataRow[]有個擴展方法CopyToDataTable()
復制代碼代碼如下:
/* 
* 補充一下,還可以利用DataView來達到檢索的目的。 
*/ 
DataTable dataSource = new DataTable(); 
DataView dv = dataSource.DefaultView; 
dv.RowFilter = "columnA = 'abc'"; 
//1.過濾后直接獲取DataTable 
DataTable newTable1 = dv.ToTable(); 
//2.設置新DataTable的TableName 
DataTable newTable2 = dv.ToTable("NewTableName"); 
//3.設置新表是否過濾重復項,擁有的列的列名以及出現的順序 
//即可以設置新表的字段。但是字段名肯定是老表dataSource中擁有的。 
DataTable newTable3 = 
dv.ToTable(true, new string[] { "columnA,columnF,columnC" }); 
//4.綜合了2.3兩點。 
DataTable newTable4 = 
dv.ToTable("NewTableName", true, new string[] { "columnA,columnF,columnC" });
 

C#中DataTable刪除行的方法,分享給大家供大家參考之用。具體實現方法如下:

自己的刪除例子(drTemp是表,gvSummary是dev 的gridview。單擊右鍵點擊grid刪除):

1、dtTemp.Rows.RemoveAt(gvSummary.FocusedRowHandle);

2、dtTemp.Rows[gvSummary.FocusedRowHandle].Delete();  dtTemp.AcceptChanges();

在C#中,如果要刪除DataTable中的某一行,大致有以下幾種辦法:

1.如果只是想刪除datatable中的一行,可以用DataRow的delete,但是必須要刪除后讓DataTable知道,所以就要用到.AcceptChanges()方法,原因是這種刪除只是標識性刪除,就像我們通常在數據庫中用到的IsDelete字段。

Delete()之后需要datatable.AccepteChanges()方法確認完全刪除,因為Delete()只是將相應列的狀態標志為刪除,還可以通過datatable.RejectChanges()回滾,使該行取消刪除。

2.徹底刪除就要用到datatable的.Rows.Remove(DataRow dr)方法,同理也只是刪除一行可以,如果要循環刪除請繼續往下看。

3.循環徹底刪除就要用.Rows.RemoveAt(int index)方法,所以如果你是foreach的愛好者,在此請你換換口味,還有如果你是for的i++的忠實fans也希望你能換個思維。先看一下上面程序的正向寫法(錯誤的,不可用)

?
1
2
3
4
5
for ( int i = 0, j = dt.Rows.Count; i < j; i++)
{
   if (Convert.ToInt32(dt.Rows[i][ "RowID" ]) == RowID)
  dt.Rows.RemoveAt(i);
}

這個的錯誤在於datatable的RemoveAt()會在刪除后更新dataTable的index,所以你要刪除的index可能已經不是你的符合Convert.ToInt32(dt.Rows[i]["RowID"]) == RowID的index了,甚者還會拋出異常,說你訪問的index不存在。

還是要慎用datatable.Rows.RemoveAt(i),若要刪除多行,可以連續用Delete(),然后采用AccepteChanges()方法確認刪除。

使用select方法:

先把要刪除的記錄標記一下,然后select刪除行,實例代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
for ( int i = 0; i < len; i++)
{
   if (((CheckBox)Rp.Items[i].FindControl( "CB" )).Checked)
   {
  dt.Rows[i][ "C0" ] = 1; //標記要刪除的記錄
   }
}
foreach (DataRow r in dt.Select( "c0=1" ))
{
   r.Delete();
}
Rp.DataSource = dt;
Rp.DataBind();

感興趣的朋友可以測試運行本文實例以加深理解,希望本文所述對大家C#程序設計的學習有所幫助。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM