分享

DataTable 删除重复行的问题

 woshishenxiande 2011-06-22
DataTable 删除重复行的问题
2010-05-19 19:01

对于表的定义如下:



在查询数据库select语句:select * from teleOffice,之后返回一个DataTable Dt_Select。

代码参考:

string connectionStr = @"Database=spatial;Server=127.0.0.1,7788;User ID=sa;Password=90900909;";//Integrated Security=true
            SqlConnection Conn = new SqlConnection(connectionStr);
            string SQL_SELECT = "select * from teleOffice";
            SqlDataAdapter ad = new SqlDataAdapter();
            SqlCommand myCmd = new SqlCommand(SQL_SELECT,Conn);
            ad.SelectCommand = myCmd;
           DataTable Dt_select = new DataTable();
            ad.Fill(Dt_select );

另外一个DataTable 是我从Excel读出来的DataTable Dt_Excel。其中,满足两个表的结构相同条件。

使用DataTable.Merge(DataTable):

Dt_Excel.Merge(Dt_select);

自然就出现了重复行的问题。怎么解决呢?

在网上搜索了比较常见的解决方法:

用DataView进行转换:

            DataView dv = Dt_Excel.DefaultView;
            DataTable dtDistinct = dv.ToTable(true,new string[] { "TeleOfficeId", "TeleOfficeName", "GPSX", "GPSY", "Province", "city" });

           dataGridView2.DataSource = Dt_Excel;//查看结果

我试了好几次,通过DataGridView查看Dt_Excel之后,我失望了!完全没有达到“归并删除”的效果:重复行没有被删除。这是怎么回事呢?

我又经过了几次下列的尝试:

尝试一: 只显示teleOffice表的varchar()

 

            DataView dv = Dt_Excel.DefaultView;
            DataTable dtDistinct = dv.ToTable(true,new string[] { "TeleOfficeId", "TeleOfficeName" });

           dataGridView2.DataSource = Dt_Excel;//查看结果

删除重复行,成功!

尝试二:DataView dv = Dt_Excel.DefaultView;
            DataTable dtDistinct = dv.ToTable(true,new string[] { "Province", "city"});

想了一下原因:

因为定义的GPSX 和GPSY 是float类型的,而"Province", "city"两个属性虽是varchar类型的,但是数据表中,却是空值。所以不能进行“归并删除”!

怎么办呢?

看来只能自己写一个了!

其实也很简单。

private DataTable deleteRow(DataTable Dt)
        {
            for (int i = 0; i < Dt.Rows.Count; i++ )
            {              
                for ( int j = Dt.Rows.Count -1; j >= i; j --)
                {
                    int k = 0;
                    for (; k < Dt.Columns.Count; k++ )
                    {
                        if (Dt.Rows[i][k].ToString() != Dt.Rows[j][k].ToString())
                        {
                            break;
                        }
                    }
                    if (k == Dt.Columns.Count)
                    {//the Rows[i] and Row[j] are the same
                        Dt.Rows.RemoveAt(j);                        
                        break;
                    }
                }
            }
            return Dt;
        }

这个函数返回的Dt即为所求!

在使用Dt.Rows.RemoveAt(j); 之前,也遇到了问题:

我使用的是:Dt.Rows[j].delete() 时候出现“不能通过已删除的行访问该行的信息”的错误。单步跟踪Dt.Rows.Count,发现执行Dt.Rows[j].delete() 之后Dt.Rows.Count没有变化,强大的搜索呀!终于找到了!

解决办法如下:(果然是前辈的亲身体验啊!解决了问题不说,还找到了病根,在此感谢!!!)

引用:

采用datatable.Rows[i].Delete()删除行后再访问该表时出现“”的错误。原因如下:

Delete()之后需要datatable.AccepteChanges()方法确认完全删除,因为Delete()只是将相应列的状态标志为删除,还可以通过datatable.RejectChanges()回滚,使该行取消删除。

所以如果要彻底删除datarow,需要Delete()和AccepteChanges()方 法同时使用,或者采用datatable.Rows.RemoveAt(i)方法直接删除,其中i表示行索引,还有一个就是 datatable.Rows.Remove(DataRow dr)删除指定行。

不过使用datatable.Rows.RemoveAt(i)要注意,如果连续使用 datatable.Rows.RemoveAt(0);datatable.Rows.RemoveAt(1);这时并不是删除了原表中的0,1行,而 是删除0行后,原来的1行就变成了0行,所以datatable.Rows.RemoveAt(1)实际删除的是原表的2行。

所以还是要慎用datatable.Rows.RemoveAt(i),若要删除多行,可以连续用Delete(),然后采用AccepteChanges()方法确认删除。

自此问题全都解决了!

日志记载一下!

方便下次使用!

 

           dataGridView2.DataSource = Dt_Excel;//查看结果

同样失败!

尝试三:DataView dv = Dt_Excel.DefaultView;
            DataTable dtDistinct = dv.ToTable(true,new string[] { "GPSX", "GPSY"});

           dataGridView2.DataSource = Dt_Excel;//查看结果

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多