当前位置:编程学习 > C#/ASP.NET >>

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中还有没有数据。这样遇到特殊情况,也会省点时间。 --------------------编程问答--------------------
引用 8 楼 gsz_stylm 的回复:
我的思路是,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的非交集了。 --------------------编程问答-------------------- 空间和时间总是那么矛盾
--------------------编程问答--------------------
引用楼主 cdsnvip 的回复:
WebForm C# 两个 DataTable 对比删除重复?
A 表 1000行
B 表 200行( 这200行存在 A表 中)
求一速度比较快的删除  A表里 存在 于B表里的数据。
即 最终会得到 A表 800 行

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)
不同的就用 游标判断
--------------------编程问答--------------------
引用 15 楼 qian19790901 的回复:
表结构相同的  用联合查询就好了  自动过滤的(select * from A UNION  select * from B)
不同的就用 游标判断
不错 --------------------编程问答-------------------- Attendant, checkout --------------------编程问答-------------------- linq
应该可以解决 --------------------编程问答-------------------- 加油加油 --------------------编程问答--------------------
引用 12 楼 xray2005 的回复:
换个思路。

就是取 !交集(非交集) ,那么直接用LINQ来取。

假设dt1和dt2通过名为Id的int类型字段关联,
那么

C# code

   DataTable dt1 = new DataTable();
            DataTable dt2 = new DataTable();

            var dt3 = from r in……

LinQ --------------------编程问答-------------------- 直接在程序中对两个 DataTable 进行操作效率不是很高,如果两表的数据是来自于数据库,最好在数据提取之前做删除处理,当然采用存储过程来操作,效率会更高。 --------------------编程问答-------------------- 首先,要知道你的表里是不是有单一的Key,如果有就方便些,设置Table的Key,然后很容易删掉,毕竟你的数据相对的有点点多,如果循环的话效率应该不高,而且这个不是服务器作的工作,放在客户机上可能影响性能,你还是找下Key。
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,