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

我的方法就是将数据拿出来后,在业务逻辑层,用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。
创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。