最近的一个项目中,要求用一个视图来表示数张表联合查询的结果,这个倒好做。但是在页面显示的时候,要求按一定顺序来显示,如果是每一行数据在一张表里的话,只需在视图中添加一列当标识就可以,但是有几行数据是在一张表里的,查询出来后的顺序不符合页面显示,虽然可以改变表的排序方式,但是感觉太麻烦,以后可能不好改,所以就用了一种笨方法,可能会对效率有影响,如果有更好的方法,大家一定要告诉我(⌒_⌒)。
为东源等地区用户提供了全套网页设计制作服务,及东源网站建设行业解决方案。主营业务为网站建设、成都网站建设、东源网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
我的方法就是将数据拿出来后,在业务逻辑层,用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。