C#之DataTable的操作

一,合并

有时我们知道了两个DataTable1和DataTable2,我们希望将它们合并为一个新的DataTable(下面的例子中命名为了newDataTable),这就分为两种情况:DataTable1和DataTable2结构相同、DataTable1和DataTable2结构不同,下面分别介绍怎么进行合并。

1、DataTable1DataTable2结构相同的情况,结构相同我们只需要把两者的数据罗列到一块就可以了

首先初始化相同结构DataTable(测试用的)

 1 void InitDataTable1(DataTable dt)   {             
 2     dt.Columns.Add("student_no");             
 3     dt.Columns.Add("student_name");            
 4     dt.Rows.Add("001", "June");             
 5     dt.Rows.Add("002", "zhang");             
 6     dt.Rows.Add("003", "jun");         
 7 }         
 8 void InitDataTable2(DataTable dt)   {             
 9     dt.Columns.Add("student_no");             
10     dt.Columns.Add("student_name");             
11     dt.Rows.Add("111", "ABC");             
12     dt.Rows.Add("222", "XYZ");             
13     dt.Rows.Add("333", "OPQ");         
14 }
View Code

合并方法1:用Rows.Add方法

DataTable newDataTable = DataTable1.Clone();
object[] obj = new object[newDataTable.Columns.Count]; 
//添加DataTable1的数据             
for (int i = 0; i < DataTable1.Rows.Count; i++) { 
    DataTable1.Rows[i].ItemArray.CopyTo(obj, 0);
    newDataTable.Rows.Add(obj);             
}             
//添加DataTable2的数据
for (int i = 0; i < DataTable2.Rows.Count; i++)  {                
 DataTable2.Rows[i].ItemArray.CopyTo(obj, 0);                 
newDataTable.Rows.Add(obj);             
}
View Code

合并方法2:用DataTable.ImportRow方法

//拷贝DataTable1的结构和数据             
DataTable newDataTable = DataTable1.Copy();            
 //添加DataTable2的数据             
foreach (DataRow dr in DataTable2.Rows)  {                
     newDataTable.ImportRow(dr);            
} 
View Code

其实添加DataTable1的结构和数据有两种方法

//克隆DataTable1的结构             
DataTable newDataTable = DataTable1.Clone();
object[] obj = new object[newDataTable.Columns.Count];             
//添加DataTable1的数据            
for (int i = 0; i < DataTable1.Rows.Count; i++) {                 
    DataTable1.Rows[i].ItemArray.CopyTo(obj, 0);                
     newDataTable.Rows.Add(obj);             
}
//或自带的Copy方法:
DataTable newDataTable = DataTable1.Copy(); 
View Code

2、DataTable1DataTable2结构不同相同的情况,我们可以先向新表中添加DataTable1的数据,然后再向每行的后面添加添加DataTable2的数据,注意两者的行数不一定相同。

首先初始化相同结构DataTable(测试用的)

void InitDataTable1(DataTable dt) {             
    dt.Columns.Add("student_no1");             
    dt.Columns.Add("student_name1");             
    dt.Rows.Add("001", "June");             
    dt.Rows.Add("002", "zhang");            
     //dt.Rows.Add("003", "jun");         
}         
void InitDataTable2(DataTable dt) {             
    dt.Columns.Add("student_no2");             
    dt.Columns.Add("student_name2");             
    dt.Rows.Add("111", "ABC");             
    dt.Rows.Add("222", "XYZ");             
    dt.Rows.Add("222", "ASD");         
}
View Code

方法(1)先添加第一个表,再添加第二个表

/// <summary>         
/// 将两个列不同(结构不同)的DataTable合并成一个新的DataTable         
/// </summary>          
/// <param name="DataTable1">表1</param>          
/// <param name="DataTable2">表2</param>          
/// <param name="DTName">合并后新的表名</param>          
/// <returns>合并后的新表</returns>          
private DataTable UniteDataTable(DataTable DataTable1, DataTable DataTable2, string DTName) {            
     //克隆DataTable1的结构             
    DataTable newDataTable = DataTable1.Clone();             
    for (int i = 0; i < DataTable2.Columns.Count; i++) {                
         //再向新表中加入DataTable2的列结构                 
        newDataTable.Columns.Add(DataTable2.Columns[i].ColumnName);             
    }            
    object[] obj = new object[newDataTable.Columns.Count];             
    //添加DataTable1的数据             
    for (int i = 0; i < DataTable1.Rows.Count; i++) {                 
        DataTable1.Rows[i].ItemArray.CopyTo(obj, 0);                 
        newDataTable.Rows.Add(obj);             
    }
    if (DataTable1.Rows.Count >= DataTable2.Rows.Count)  {
        for (int i = 0; i < DataTable2.Rows.Count; i++) {                    
            for (int j = 0; j < DataTable2.Columns.Count; j++){ 
                newDataTable.Rows[i][j + DataTable1.Columns.Count] = DataTable2.Rows[i][j].ToString();
            }}}            
    else {                 
        DataRow dr3;                
        //向新表中添加多出的几行                 
        for (int i = 0; i < DataTable2.Rows.Count - DataTable1.Rows.Count; i++){
             dr3 = newDataTable.NewRow();                     
             newDataTable.Rows.Add(dr3);                 
        }                 
        for (int i = 0; i < DataTable2.Rows.Count; i++) {                     
             for (int j = 0; j < DataTable2.Columns.Count; j++){
                 newDataTable.Rows[i][j + DataTable1.Columns.Count] = DataTable2.Rows[i][j].ToString();
              }}}             
        newDataTable.TableName = DTName; //设置DT的名字    }       return newDataTable;
}
View Code

方法(2)先添加行数多的表。其实我们也可以先判断哪个表的行数多,就先添加哪个表,然后再添加行少的表就可以了。

     /// <summary>
        /// 将两个列不同(结构不同)的DataTable合并成一个新的DataTable
        /// </summary>
        /// <param name="DataTable1">表1</param>
        /// <param name="DataTable2">表2</param>
        /// <param name="DTName">合并后新的表名</param>
        /// <returns>合并后的新表</returns>
        private DataTable UniteDataTable2(DataTable DataTable1, DataTable DataTable2, string DTName)
        {
            DataTable newDataTable = new DataTable();
            if (DataTable1.Rows.Count > DataTable2.Rows.Count)
            {
                newDataTable = FillData(DataTable1, DataTable2);
            }
            else
            {
                newDataTable = FillData(DataTable2, DataTable1);
            }
            newDataTable.TableName = DTName; //设置DT的名字   
            return newDataTable;
        }
        private DataTable FillData(DataTable dt1, DataTable dt2)
        {
            //克隆DataTable1的结构   
            DataTable newDataTable = dt1.Clone();
            for (int i = 0; i < dt2.Columns.Count; i++)
            {
                //再向新表中加入DataTable2的列结构     
                newDataTable.Columns.Add(dt2.Columns[i].ColumnName);
            }
            object[] obj = new object[newDataTable.Columns.Count];
            //添加DataTable1的数据   
            for (int i = 0; i < dt1.Rows.Count; i++)
            {
                dt1.Rows[i].ItemArray.CopyTo(obj, 0);
                newDataTable.Rows.Add(obj);
            }
            for (int i = 0; i < dt2.Rows.Count; i++)
            {
                for (int j = 0; j < dt2.Columns.Count; j++)
                {
                    newDataTable.Rows[i][j + dt1.Columns.Count] = dt2.Rows[i][j].ToString();
                }
            }
            return newDataTable;
        }
View Code

二,比较

如果两个datatable的字段完全一致的话,可以直接使用Except,Intersect 

注:需引入linq. 
//与免打扰中的用户进行比较,筛选出可以正常接收推送的用户 
var normalReceive = dtUser.AsEnumerable().Except(dtDND.AsEnumerable(), DataRowComparer.Default); 
//比对两个表的用户名一致的,保存username到list中 
var intersectUser = dtUserPower.AsEnumerable().Intersect(normalReceive, DataRowComparer.Default);
foreach (var item in intersectUser){    
  listTemp.Add(item["username"].ToString());
}
View Code

如果两个datatable中有部分字段相同,也就是说有可进行比对的字段的话。

//与免打扰中的用户进行比较,筛选出可以正常接收推送的用户 
var normalReceive = from r in dtUser.AsEnumerable() 
    where !(from rr in dtDND.AsEnumerable() select rr.Field<string>("username")).Contains( r.Field<string>("username")) 
  select r; 
//比对两个表的用户名一致的,保存token到list中 
var intersectUser = from r in normalReceive.AsEnumerable() 
    where (from rr in dtUserPower.AsEnumerable() select rr.Field<string>("username")).Contains( r.Field<string>("username")) 
  select r; 
foreach (var item in intersectUser) {   
listTemp.Add(item["token"].ToString()); 
}
View Code

三,行列提取

1)取行,通过DataView筛选:一般用rowfilter

DataTable datSource;//数据源表
//过滤表
DataView davTemp = new DataView(datSource, "过滤条件", "排序字段", DataViewRowState.各种 状态);
//把过滤后的表赋给新表
DataTable datNew = davTemp.ToTable(); 
// 或者
DataView davTemp = new DataView(datSource);
davTemp.RowFilter=" where 子句";  // 例如:davTemp.RowFilter="UserName='xxxx' ";  

2)取表的某列或多列

DataTable datSource;//数据源表
DataTable datNew= datSource.DefaultView.ToTable(false, new string[] { "列名", "列名" .....});//或:(false,"列名", "列名" ...)

3)复制某行的值[前提是表结构或列数相同

DataTable datSource;
DataTable datNew;
datSource.Rows[i].ItemArray= datNew. Rows[i].ItemArray; 

4)表列数相同,但是却列名不同,想复制值怎么办?———换个思维方式,既然列数相同,只是列名不同,为什么不改变列名呢?如下:

DataTable datSource;
DataTable datNew;
datNew= datSource.Copy();
datNew.Columns["FirstColumn"].ColumnName = "YourColumnName";

5)调整列的位置SetOrdinal();  

DataTable dat = new DataTable();   //添加三列   
dat.Columns.Add("col1");   
dat.Columns.Add("col2");   
dat.Columns.Add("col3");   
//添加一行数据    dat.Rows.Add(1,2,3);    //把第三列放到第一的位置   
dat.Columns["col3"].SetOrdinal(0);

四,新增列初始化 

//新增列的初始化
//dt.Columns.Add("scanned",typeof(Int32)); //dt.Columns["scanned"].DefaultValue = 0; DataColumn newCol = new DataColumn(); newCol.DataType = typeof(decimal); newCol.ColumnName = "scanned"; newCol.DefaultValue = 0; dt.Columns.Add(newCol);

 

posted @ 2017-03-17 15:38  ZainXiao  阅读(358)  评论(0编辑  收藏  举报