DataTabel中关于ImpotRow的一点尝试

最近的一个项目中,要求用一个视图来表示数张表联合查询的结果,这个倒好做。但是在页面显示的时候,要求按一定顺序来显示,如果是每一行数据在一张表里的话,只需在视图中添加一列当标识就可以,但是有几行数据是在一张表里的,查询出来后的顺序不符合页面显示,虽然可以改变表的排序方式,但是感觉太麻烦,以后可能不好改,所以就用了一种笨方法,可能会对效率有影响,如果有更好的方法,大家一定要告诉我(⌒_⌒)。

为东源等地区用户提供了全套网页设计制作服务,及东源网站建设行业解决方案。主营业务为网站建设、成都网站建设、东源网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

 

我的方法就是将数据拿出来后,在业务逻辑层,用DataTable实例的Select()方法,查询出指定的列,然后将其加入到一个空的,表架构相同的表中(Clone()方法),这是希望整行插入到表中的,如果一个单元格一个单元格的复制,那就太没效率了(●''●),虽然我这个也没什么效率啦……

然后在插入的时候遇到了问题

 DataTable dt = new DataTable();
 dt.Columns.Add("A");
 dt.Columns.Add("B");
 dt.Columns.Add("C");
DataRow dr = dt.NewRow();
 
//处理dr中的数据
 
dt.Rows.Add(dr);

这是标准写法。

DataTable dt = new DataTable();
 dt.Columns.Add("A");
 dt.Columns.Add("B");
 dt.Columns.Add("C");
DataRow dr = dt.NewRow();
 
DataTable dt2 = dt.Clone();
 
//处理dr中的数据
 
dt2.Rows.Add(dr);

但是这样写就会报错,“该行已经属于另一个表。”

这是因为dr的Table属性是指向dt的。

但是现在查看dt.Row.Count时,发现是0,而不是1呢?

这涉及到一个DataRowState 的问题

DataRowState有5种状态

Detached该行已被创建,但不属于任何 System.Data.DataRowCollection。System.Data.DataRow在以下情况下立即处于此状态:创建之后添加到集合中之前;或从集合中移除之后。
Unchanged该行自上次调用 System.Data.DataRow.AcceptChanges()以来尚未更改。
Added

该行已添加到System.Data.DataRowCollection中,System.Data.DataRow

.AcceptChanges()尚未调用。
Deleted该行已通过 System.Data.DataRow的 System.Data.DataRow.Delete()方法被删除。
Modified该行已通过 System.Data.DataRow的 System.Data.DataRow.Delete()方法被删除。

DataRow dr = dt.NewRow();
//创建dr后,dr的DataRowState为Detached
 
dt2.Rows.Add(dr);
// dr的DataRowState为Added

也就是状态的更改。

  但是如果我们把dt2.Rows.Add(dr)换成dt2.Rows.ImportRow(dr)后,发现dt中仍然没有dr,也就是dt.Row.Count为0。这是因为ImportRow方法负责复制dr到dt中,包括DataRowState。但是复制的时候会改标dr的Table的指向,也就是指向当前调用ImportRow方法的DataTable。


例如:

DataTable dt,dt2;
DataRow dr;
 
dt = new DataTable();
dt.Columns.Add("A");
dt.Columns.Add("B");
dt.Columns.Add("C");
 
dr = dt.NewRow();
 
dt2 = dt.Clone();
 
if (dt2.Rows[0].Table == dt)
{
     Console.WriteLine("dt2=dt");
 }
 
 if (dt.Rows[0] == dr)
 {
     Console.WriteLine("dt=dr");
 }
 
 if (dt2.Rows[0] == dr)
 {
     Console.WriteLine("dt2=dr");
 }

输出结果:

dt=dr

  但是我们的目标是将挑选出来的行,添加到相同结构的空表中,对于挑选的结果行,是能添加到空表中的,因为如果是从一个DataTable中取出DataRow,那么这个DataRow的DataRowState是Add,也就是使用ImportRow方法添加到空表后可以看到结果,如果是通过dt = new DataTable()创建的且未添加到DataTable的DataRow,使用ImportRow方法添加到空表后是看不到结果的。

DataTable dt,dt2;
DataRow dr,dr2;
 
dt = new DataTable();
dt.Columns.Add("A");
dt.Columns.Add("B");
dt.Columns.Add("C");
 
dr = dt.NewRow();
 
dr2 = dt.NewRow();
 
dt2 = dt.Clone();
 
dt.Rows.Add(dr);
 
dt2.ImportRow(dr2);
 
Console.WriteLine(dt2.Rows.Count.ToString());
 
dt2.ImportRow(dt.Rows[0]);
 
Console.WriteLine(dt2.Rows.Count.ToString());

 

结果:

0

1

 

注意:ImportRow方法是复制DataRow,也就是说会创建一个新的DataRow,而不是引用原来的DataRow。


网站标题:DataTabel中关于ImpotRow的一点尝试
地址分享:http://myzitong.com/article/ipdcjc.html