C#之DataTable的操作
一,合并
有时我们知道了两个DataTable1和DataTable2,我们希望将它们合并为一个新的DataTable(下面的例子中命名为了newDataTable),这就分为两种情况:DataTable1和DataTable2结构相同、DataTable1和DataTable2结构不同,下面分别介绍怎么进行合并。
1、DataTable1和DataTable2结构相同的情况,结构相同我们只需要把两者的数据罗列到一块就可以了
首先初始化相同结构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 }
合并方法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); }
合并方法2:用DataTable.ImportRow方法
//拷贝DataTable1的结构和数据 DataTable newDataTable = DataTable1.Copy(); //添加DataTable2的数据 foreach (DataRow dr in DataTable2.Rows) { newDataTable.ImportRow(dr); }
其实添加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();
2、DataTable1和DataTable2结构不同相同的情况,我们可以先向新表中添加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"); }
方法(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; }
方法(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; }
二,比较
如果两个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()); }
如果两个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()); }
三,行列提取
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);