对于表的定义如下:

在查询数据库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;//查看结果