WebForm C# 两个 DataTable 对比删除重复?
WebForm C# 两个 DataTable 对比删除重复?A 表 1000行
B 表 200行( 这200行存在 A表 中)
求一速度比较快的删除 A表里 存在 于B表里的数据。
即 最终会得到 A表 800 行 --------------------编程问答-------------------- 循环判断吧。 --------------------编程问答-------------------- 1000*200?
太慢了。。。 --------------------编程问答-------------------- 能否更快些 --------------------编程问答-------------------- var IDList = 200条数据的ID
delete from Table ID In('IDList ')
不知道可行否 --------------------编程问答-------------------- while(TableB.count!=0)
{
for(i=0,i<TableB.count,i++)
{
if(TabelA.Cell[i][ID]==TabelB.Cell[i][ID])
{delete from Table ID In('IDList ');Break;}
}
}
上面提供一个思路
每删除一条记录就跳出循环重新遍历以减少搜索量
写法可能有问题手头没有VS不方便你自己可以看着改改 --------------------编程问答-------------------- datagridview数据来自数据库嘛?
如果来自数据库就简单了 --------------------编程问答-------------------- 吼吼! --------------------编程问答-------------------- 我的思路是,DataTable A, DataTable B,按照一个字段(关键字段),按照同一种方法进行排序,例如 都是desc 吧,这样的话,你只用将A中的关键字段,和B中的第一个关键字段来进行比较,如果A.关键字段<B.关键字段,则A.关键字段++; A.关键字段==B.关键字段 则,删除。既然你说了,B中的数据肯定在A中,也可以直接判断
A.关键字段是否==B.关键字段,== 则删除,否则,继续。
这样,可能会省一点时间。这样循环的话,可能最多也就循环1000次,最好就是在判断一下,B中还有没有数据。这样遇到特殊情况,也会省点时间。 --------------------编程问答--------------------
楼上的方法甚好,肯定是要先排个序,然后估算匹配位置,缩小搜索范围。再进行匹配。通过中点向两边搜索 --------------------编程问答-------------------- 如果允许对A、B进行排序,那么可以对A、B按照统一字段进行排序。
然后循环B表,内循环循环是循环A表,for(;i<A.Rows.Count;i++)
注意的是只有第一次i=0; 之后逐渐变大,
例如B第一条在A中200条发现,那么B第二条肯定在A200条之后,这样搜索一
共必定是1000次。 而DataTable的排序用sort就可以。很现成的用法。
复杂度: 0(1000).
--------------------编程问答-------------------- 这样?
DataTable _Table1 = new DataTable("A1");
_Table1.Columns.Add("A");
DataTable _Table2 = new DataTable("A2");
_Table2.Columns.Add("B");
for (int i = 0; i != 1000; i++)
{
if (i <= 200) _Table2.Rows.Add(new object[] { i });
_Table1.Rows.Add(new object[] { i });
}
_Table2.PrimaryKey = new DataColumn[] { _Table2.Columns[0] };
_Table1.PrimaryKey = new DataColumn[] { _Table1.Columns[0] };
DataSet _Set = new DataSet();
_Set.Tables.Add(_Table1);
_Set.Tables.Add(_Table2);
_Table1.ChildRelations.Add("Li", _Table1.Columns[0], _Table2.Columns[0]);
DataTable _NewTable = new DataTable();
for (int i = 0; i != _Table1.Rows.Count; i++)
{
if (_Table1.Rows[i].GetChildRows("Li").Length == 0)
{
_NewTable.ImportRow(_Table1.Rows[i]);
}
} --------------------编程问答--------------------
换个思路。
就是取 !交集(非交集) ,那么直接用LINQ来取。
假设dt1和dt2通过名为Id的int类型字段关联,
那么
DataTable dt1 = new DataTable();
DataTable dt2 = new DataTable();
var dt3 = from r in dt1.AsEnumerable()
where !(
from rr in dt2.AsEnumerable()
select rr.Field<int>("Id")
).Contains(r.Field<int>("Id"))
select r;
现在dt3里面就是 dt1,dt2的非交集了。 --------------------编程问答-------------------- 空间和时间总是那么矛盾
--------------------编程问答--------------------
200次循环就可解决.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace Utility
{
public class DTHelper
{
/// <summary>
/// 取两个DataTable的交集,删除重复数据
/// </summary>
/// <param name="sourceDataTable">源DataTable</param>
/// <param name="targetDataTable">目标DataTable</param>
/// <param name="primaryKey">两个表的主键</param>
/// <returns>合并后的表</returns>
public static DataTable Merge(DataTable sourceDataTable, DataTable targetDataTable, string primaryKey)
{
if (sourceDataTable != null || targetDataTable != null || !sourceDataTable.Equals(targetDataTable))
{
sourceDataTable.PrimaryKey = new DataColumn[] { sourceDataTable.Columns[primaryKey] };
DataTable dt = targetDataTable.Copy();
foreach (DataRow tRow in dt.Rows)
{
//拒绝自上次调用 System.Data.DataRow.AcceptChanges() 以来对该行进行的所有更改。
//因为行状态为DataRowState.Deleted时无法访问ItemArray的值
tRow.RejectChanges();
//在加载数据时关闭通知、索引维护和约束。
sourceDataTable.BeginLoadData();
//查找和更新特定行。如果找不到任何匹配行,则使用给定值创建新行。
DataRow temp = sourceDataTable.LoadDataRow(tRow.ItemArray, true);
sourceDataTable.EndLoadData();
sourceDataTable.Rows.Remove(temp);
}
}
sourceDataTable.AcceptChanges();
return sourceDataTable;
}
}
}
也可以使用DataTable.Select()查找相同行,不过经测试速度略慢于上述方法. --------------------编程问答-------------------- 表结构相同的 用联合查询就好了 自动过滤的(select * from A UNION select * from B)
不同的就用 游标判断
--------------------编程问答-------------------- 不错 --------------------编程问答-------------------- Attendant, checkout --------------------编程问答-------------------- linq
应该可以解决 --------------------编程问答-------------------- 加油加油 --------------------编程问答--------------------
LinQ --------------------编程问答-------------------- 直接在程序中对两个 DataTable 进行操作效率不是很高,如果两表的数据是来自于数据库,最好在数据提取之前做删除处理,当然采用存储过程来操作,效率会更高。 --------------------编程问答-------------------- 首先,要知道你的表里是不是有单一的Key,如果有就方便些,设置Table的Key,然后很容易删掉,毕竟你的数据相对的有点点多,如果循环的话效率应该不高,而且这个不是服务器作的工作,放在客户机上可能影响性能,你还是找下Key。
补充:.NET技术 , C#