问题描述
现已查询出2个DataTable,架构不相同,有相同的一个字段。现在想合并在一个DataTable中,然后绑定到dataGrid。相同字段为ID网上找的合并datatable并不能合并到正确的匹配列。求教怎么解决?贴上合并:///<summary>///将两个列不同的DataTable合并成一个新的DataTable///</summary>///<paramname="dt1">表1</param>///<paramname="dt2">表2</param>///<paramname="DTName">合并后新的表名</param>///<returns></returns>publicstaticDataTableUniteDataTable(DataTabledt1,DataTabledt2,stringDTName){DataTabledt3=dt1.Clone();for(inti=0;i<dt2.Columns.Count;i++){dt3.Columns.Add(dt2.Columns[i].ColumnName);}object[]obj=newobject[dt3.Columns.Count];for(inti=0;i<dt1.Rows.Count;i++){dt1.Rows[i].ItemArray.CopyTo(obj,0);dt3.Rows.Add(obj);}if(dt1.Rows.Count>=dt2.Rows.Count){for(inti=0;i<dt2.Rows.Count;i++){for(intj=0;j<dt2.Columns.Count;j++){dt3.Rows[i][j+dt1.Columns.Count]=dt2.Rows[i][j].ToString();}}}else{DataRowdr3;for(inti=0;i<dt2.Rows.Count-dt1.Rows.Count;i++){dr3=dt3.NewRow();dt3.Rows.Add(dr3);}for(inti=0;i<dt2.Rows.Count;i++){for(intj=0;j<dt2.Columns.Count;j++){dt3.Rows[i][j+dt1.Columns.Count]=dt2.Rows[i][j].ToString();}}}dt3.TableName=DTName;//设置DT的名字returndt3;}
解决方案
解决方案二:
你是想根据ID来合并?上面的代码看了下,只是简单的把两个dt合并到一起的。你这个2个查询是在同一个数据库还是,可以考虑下用视图或者sql查询的时候就把结果放一起。要不就只能自己写代码来合并了。。。
解决方案三:
引用1楼jun471537173的回复:
你是想根据ID来合并?上面的代码看了下,只是简单的把两个dt合并到一起的。你这个2个查询是在同一个数据库还是,可以考虑下用视图或者sql查询的时候就把结果放一起。要不就只能自己写代码来合并了。。。
因为2个datatable查询不在同一个数据库,而且现在不让用DBLINK查询所以只能分开查询,然后合并。
解决方案四:
引用2楼u012295295的回复:
Quote: 引用1楼jun471537173的回复:
你是想根据ID来合并?上面的代码看了下,只是简单的把两个dt合并到一起的。你这个2个查询是在同一个数据库还是,可以考虑下用视图或者sql查询的时候就把结果放一起。要不就只能自己写代码来合并了。。。因为2个datatable查询不在同一个数据库,而且现在不让用DBLINK查询所以只能分开查询,然后合并。
哦,那就自己写个合并,大概就是把行数多的.Copy,然后添加非ID的列,最后循环遍历行。。。
解决方案五:
引用3楼jun471537173的回复:
Quote: 引用2楼u012295295的回复:
Quote: 引用1楼jun471537173的回复:
你是想根据ID来合并?上面的代码看了下,只是简单的把两个dt合并到一起的。你这个2个查询是在同一个数据库还是,可以考虑下用视图或者sql查询的时候就把结果放一起。要不就只能自己写代码来合并了。。。因为2个datatable查询不在同一个数据库,而且现在不让用DBLINK查询所以只能分开查询,然后合并。
哦,那就自己写个合并,大概就是把行数多的.Copy,然后添加非ID的列,最后循环遍历行。。。
合并已经写过了,不过合并后的数据是错误的。例如datatable1中id为100合并后同一列上datatable2的id却为10,所以才求教怎么合并到正确的匹配列上
解决方案六:
引用4楼u012295295的回复:
Quote: 引用3楼jun471537173的回复:
Quote: 引用2楼u012295295的回复:
Quote: 引用1楼jun471537173的回复:
你是想根据ID来合并?上面的代码看了下,只是简单的把两个dt合并到一起的。你这个2个查询是在同一个数据库还是,可以考虑下用视图或者sql查询的时候就把结果放一起。要不就只能自己写代码来合并了。。。因为2个datatable查询不在同一个数据库,而且现在不让用DBLINK查询所以只能分开查询,然后合并。
哦,那就自己写个合并,大概就是把行数多的.Copy,然后添加非ID的列,最后循环遍历行。。。
合并已经写过了,不过合并后的数据是错误的。例如datatable1中id为100合并后同一列上datatable2的id却为10,所以才求教怎么合并到正确的匹配列上
在循环中加判断,id相同的行才赋值。。。
解决方案七:
可以采用Relations关联两个dt
解决方案八:
已经找到正确的方法了。privateDataTabletable1(){DataTablet=newDataTable();t.Columns.Add("ID",Type.GetType("System.Int32"),"");t.Columns.Add("NAME",Type.GetType("System.String"),"");t.Columns.Add("NO",Type.GetType("System.Int32"),"");DataRownewRow;newRow=t.NewRow();newRow["ID"]=1;newRow["NAME"]="王明";newRow["NO"]=20100001;t.Rows.Add(newRow);newRow=t.NewRow();newRow["ID"]=2;newRow["NAME"]="张晓";newRow["NO"]=20100002;t.Rows.Add(newRow);newRow=t.NewRow();newRow["ID"]=3;newRow["NAME"]="阳姗姗";newRow["NO"]=20100003;t.Rows.Add(newRow);returnt;}
privateDataTabletable2(){DataTablet=newDataTable();t.Columns.Add("ID",Type.GetType("System.Int32"),"");t.Columns.Add("REMARK",Type.GetType("System.String"),"");t.Columns.Add("AGE",Type.GetType("System.Int32"),"");DataRownewRow;newRow=t.NewRow();newRow["ID"]=1;newRow["REMARK"]="备注信息1";newRow["AGE"]=17;t.Rows.Add(newRow);newRow=t.NewRow();newRow["ID"]=2;newRow["REMARK"]="备注信息2";newRow["AGE"]=16;t.Rows.Add(newRow);returnt;}
privatevoiduniteTable(){DataTablet1=table1();DataTablet2=table2();DataTablenewTable=newDataTable();newTable.Columns.Add("ID",Type.GetType("System.Int32"),"");newTable.Columns.Add("NO",Type.GetType("System.Int32"),"");newTable.Columns.Add("NAME",Type.GetType("System.String"),"");newTable.Columns.Add("AGE",Type.GetType("System.Int32"),"");newTable.Columns.Add("REMARK",Type.GetType("System.String"),"");if(t1.Rows.Count>=t2.Rows.Count){newTable.Merge(t1);foreach(DataRownewrowinnewTable.Rows){foreach(DataRowdr2int2.Rows){if(newrow["ID"].ToString()==dr2["ID"].ToString()){newrow["AGE"]=dr2["AGE"];newrow["REMARK"]=dr2["REMARK"];}}}}else{newTable.Merge(t2);foreach(DataRownewrowinnewTable.Rows){foreach(DataRowdr1int1.Rows){if(newrow["ID"].ToString()==dr1["ID"].ToString()){newrow["NO"]=dr1["NO"];newrow["NAME"]=dr1["NAME"];}}}}}
大致就是这样了
解决方案九:
引用7楼u012295295的回复:
已经找到正确的方法了。
“笛卡尔积”跟“使用ID字段进行关联”,产生的数据行数是一样的吗?假设某个数据下,第一个表有1万行,第二个表有1千行,正常的“合并”结果只应该有1万5千行,而你却产生1千万行的一个Table。这不可能是“正确的方法”。
解决方案十:
引用8楼sp1234的回复:
Quote: 引用7楼u012295295的回复:
已经找到正确的方法了。“笛卡尔积”跟“使用ID字段进行关联”,产生的数据行数是一样的吗?假设某个数据下,第一个表有1万行,第二个表有1千行,正常的“合并”结果只应该有1万5千行,而你却产生1千万行的一个Table。这不可能是“正确的方法”。
其实我需要的就是已第二个表的数据为主要,因为现在公司不让用DBLINK连接查询,所以才不得已用2个datatable来的。
解决方案十一:
如果换成10年前滴程序员,如果我们说“采用Relations关联两个dt”,他会里面google“Relations关联datatable”是个什么含义,难道你让我们百度出来,贴给你么??好吧,这是百度出滴第一版第1条的记录http://www.cnblogs.com/beeone/p/3618095.html
解决方案十二:
引用10楼wanghui0380的回复:
好吧,这是百度出滴第一版第1条的记录http://www.cnblogs.com/beeone/p/3618095.html
解决方案十三:
DataTablet1=newDataTable();DataTablet2=newDataTable();t1.Columns.Add("id",typeof(int));t1.Columns.Add("name",typeof(string));for(inti=0;i<10;i++){DataRowrow=t1.NewRow();row[0]=i;row[1]="name"+i.ToString();t1.Rows.Add(row);}t2.Columns.Add("id",typeof(int));t2.Columns.Add("desc",typeof(string));DataRowr=t2.NewRow();r[0]=3;r[1]="desc3";t2.Rows.Add(r);DataRowr2=t2.NewRow();r2[0]=4;r2[1]="desc4";t2.Rows.Add(r2);DataRowr3=t2.NewRow();r3[0]=43;r3[1]="desc43";t2.Rows.Add(r3);varreslut=(frombint1.AsEnumerable()joinaint2.AsEnumerable()onb.Field<int>("id")equalsa.Field<int>("id")intotempfromtintemp.DefaultIfEmpty()selectnew{ID=b.Field<int>("id"),Name=b.Field<string>("Name"),Desc=t==null?"":t.Field<string>("desc")}).ToList();
解决方案十四:
引用10楼wanghui0380的回复:
如果换成10年前滴程序员,如果我们说“采用Relations关联两个dt”,他会里面google“Relations关联datatable”是个什么含义,难道你让我们百度出来,贴给你么??好吧,这是百度出滴第一版第1条的记录http://www.cnblogs.com/beeone/p/3618095.html
你看我上面,其实我就是根据你的提示,已经自己找到了。感觉需要的就是一个思路,自己一个人想,总是容易想到死胡同去了。