DataSet 对象是支持 ADO.NET的断开式、分布式数据方案的核心对象 ,用途非常广泛.我们很多时候需要使用其中的数据,比如取得一个DataTable的数据或者复制另一个DataTabe中的数据或者是DataRow的数据,但是只有DataSet和DataTable的复制是支持深层复制的,就是说不仅能复制元素的结构,而且能复制元素的数据,而DatatDataRow没有相关的复制的方法,下面将简单介绍下这些数据元素的复制问题。

DataTable sourceTable;
DataTable objectTable;
DatatDataRow sourceRow;
DatatDataRow objectRow;
DataRow tempRow;
DataSet souceDataSet = new DataSet();

复制DataSet

 DataSet object = souceDataSet.Copy();//深复制
 DataSet object = souceDataSet.Clone();//浅复制,只复制架构

复制DataTable

 objectTable  = sourceTable .Copy();//深复制
 objectTable  = sourceTable .Clone();//浅复制,只复制架构

复制DataRow

   项目开发中经常遇到这种错误-“此行已属于另一个表” 。导致这个错误的语句如下:



objectTable .Rows.Add(SourceDataRow);



     分析了一下原因,因为DataRow DataTable 都是传引用调用的。所以一个行在一个表中了,就不能再增加到另外一个表。


具体方法:


1  ImportRow方法:public void ImportRow( DataRow DataRow);

objectTable = sourceTable.clone();//必须先复制表的架构,使具有相同的的列或关系!
foreach (DataRow oRow in sourceTable)
{  

      objectTable.ImportRow(oRow);//在objectTable中添加一个新行,并将sourceRow的值复制进去,要求表的结构一样!

}

_____________________________________________________________________________________________________

2. 循环DataTable的每个列

DataRow aDataRow = objectTable.NewRow();

foreach(DataColumn aDataColumn in sourceTable.Columns)

{

aDataRow [aDataColumn.ColumnName] = sourceTable[i][aDataColumn.ColumnName];

}

   objectTable.Rows.Add(aDataRow);

3. 自定义复制

objectTable.Columns.Add ("id");//不需要有一样的架构,只复制自己需要的列!  
Object [] myArry = new Object [1];  
  foreach (DataRow oRow in sourceTable)
{  

 tempRow = objectTable.NewRow();//此方法必须调用!
 myArry[0] = oRow["id"];//如果myArry中没有源表中的id列的话就会报错!
 tempRow.ItemArray = myArry;//ItemArray属性为Object类型数组,根据程序的需要需要可自行复制多个列的数据!
 objectTable.Rows.Add(tempRow); //此方法必须调用,否则DataRow中的数据将不能显示!

}
_____________________________________________________________________________________________________

4. LoadDataRow方法:public DataRow LoadDataRow(Object[] values,bool fAcceptChanges);

   Object[] newRow = new Object[3];
  // 设置对象数组的值
   newRow[0] = "Hello";
   newRow[1] = "World";
   newRow[2] = "two";
   DataRow myRow;
   ObjectTable.BeginLoadData();
   // 将新行添加到表中
   myRow = ObjectTable.LoadDataRow(newRow, true);//标志要设置为true,表示添加新行
   ObjectTable.EndLoadData();


该方法比较复杂,如果只是简单的复制现有行的数据来添加新行的话建议不要采用,具体用法请参看sdk文挡。


DataTable.ImportRow ()方法的一个问题

http://blog.163.com/xiao_mege/blog/static/7294275320108454814938/

DataTable.ImportRow 方法--在数据表DataTable之间复制数据行DataRow

2010-09-04 17:43:03|  分类:ASP.NET|  标签:datatableimportrowdatarow|举报|字号订阅

DataRow复制到 DataTable中,保留任何属性设置以及初始值和当前值。

调用 NewRow时,将使用现有的表架构向表中添加一行,并为该行填充默认值,同时将DataRowState设置为 Added。调用ImportRow将保留现有的 DataRowState以及该行中的其他值。如果作为参数传递的 DataRow处于分离状态,则忽略它,并且不引发异常。

C# 数据表之间复制数据行--(datatable、ImportRow 、Copy 简单)

http://blog.163.com/xiao_mege/blog/static/7294275320108595937957/



2010-09-04 17:55:13|  分类: ASP.NET |  标签:dtdatatabledatarowimportrowrows  |举报 |字号订阅

今天想操纵虚拟表DataTable,可是创建了DataRow对象往DataTable.Rows里添加时总说此行已经属于另一个表,于是想到了ImportRow这个方法,但是使用后,发现DataTable.Rows并没有添加值。
缩略代码如下:
Code Snippet
DataTable dt = new DataTable();
           DataColumndc = newDataColumn("name",System.Type.GetType("System.String"));
           dt.Columns.Add(dc);
           DataRowdr = dt.NewRow();
           dr["name"]= "aaa";
           dt.ImportRow(dr);
           MessageBox.Show(dt.Rows.Count.ToString());

大家用过这个方法没?谈下心得。

一、

你说“因为NewRow()是依据dt的架构来创建一个新行,并不属于dt,并且我的程序MessageBox.Show(dt.Rows.Count.ToString())得到的就是0,说明dt未有任何行”。


你这样说并不正确,使用NewRow()来创建一个DataRow的确会创建一个隶属于当前DataTable的且架构相同DataRow,要理解这个,你首先要理解DataRow的状态,这由DataRowState枚举暴露出来,请看以下MSDN的解释:


Detached

该行已被创建,但不属于任何DataRowCollectionDataRow在以下情况下立即处于此状态:创建之后添加到集合中之前;或从集合中移除之后。

Unchanged

该行自上次调用AcceptChanges以来尚未更改。

Added

该行已添加到DataRowCollection中,AcceptChanges尚未调用。

Deleted

该行已通过DataRowDelete方法被删除。

Modified

该行已被修改,AcceptChanges尚未调用。


看到Detached状态了吗?当你用NewRow()方法来创建出了一个新的DataRow时而且没有使用Add()方法加入当前DataTable时,它的状态就是Detached,你可以使用DataRow.RowState 属性来验证。虽然dt.Rows.Count.ToString()结果是零,但是你调用DataRow.Table属性时,就会返回当前的DataTable。当你调用Add方法添加DataRow,它的状态就会变为Added。


因此使用NewRow方法()创建出的DataRow隶属于DataTable是绝对正确的。

二、


ImportRow()方法不是这样使用的,它是将已经存在的DataRow复制到新的DataTable,请你看看下面的使用示例:

SQL1 = "select name as 姓名 ,age as 年龄 fromusers";  
//---- datatable1
SQL1 = "select name as 姓名 ,age as 年龄 from Employee";
// ----datatable2
//将datatable2中的所有记录合到datatable1中
//使用DataTable.ImportRow 方法,将 DataRow 复制到DataTable中,保留任何属性设置以及初始值和当前值。
DataRow[] foundRows = datatable2.Select();
for(int i= 0;i<foundRows.Length;i++)
{
   datatable1.ImportRow(foundRowsIdea);
}

三、

dt.Rows.Add(dr);



ImportRow一般用在将一个表导入到另外一个表


例如

DataTable dt = new DataTable();
DataColumn dc = new DataColumn("name",System.Type.GetType("System.String"));
dt.Columns.Add(dc);
for (int i = 0; i < 10; i++)
{
 DataRow dr = dt.NewRow();
 dr["name"] = "aaa";
 dt.Rows.Add(dr);
}


DataTable dt2 = new DataTable();
DataColumn dc2 = new DataColumn("name",System.Type.GetType("System.String"));  
dt2.Columns.Add(dc2);

for (int i = 0; i < dt.Rows.Count; i++)
{

 dt2.ImportRow(dt.Rows[i]);
}


MessageBox.Show(dt.Rows.Count.ToString());
MessageBox.Show(dt2.Rows.Count.ToString());

四、

你首先要明白,ImportRow()方法必须是用来将其他表的DataRow复制到当前的表,如果是复制自己的DataRow毫无意义,是不会成功的。请看你写的代码:

         DataTable dt = new DataTable();
           DataColumndc = newDataColumn("name",System.Type.GetType("System.String"));
           dt.Columns.Add(dc);
DataRow dr = dt.NewRow();
           dr["name"]= "aaa";
dt.ImportRow(dr);
           MessageBox.Show(dt.Rows.Count.ToString());

第 一句和第二句红色的代码就导致了使用importRow是不会成功的,因为首先dt.NewRow()方法就会创建一个和dt这个dataTable相关 联的行,也就是说你已经指定这个dr就是属于dt的,你再用dt.ImportRow(dr)方法,这表示向dt复制一个属于自己的DataRow,这当然就不会成功了。

至于你问table.ImportRow()方法传递的参数DataRow应该和table拥有相同的结构吗?
这当然是一定的了。

五、

MSDN上的解释“

DataRow复制到 DataTable中,保留任何属性设置以及初始值和当前值。

并没有指明是哪个表的行,所以我当初弄错,不过要说明一点的就是,你说dr=dt.NewRow()指明dr本身就是dt的,我觉得这个说法不妥,因为NewRow()是依据dt的架构来创建一个新行,并不属于dt,并且我的程序MessageBox.Show(dt.Rows.Count.ToString())得到的就是0,说明dt未有任何行。不知道我的说法对不对,还请指 教。

另外我写这个需求就是两张表,tableA,和tableB,A表有字段A,B,C。 B表有字段A,B,C,D,E,B表是从数据库中读出来的一条记录集,我创建了一个A表的新行dr去接收B表的A,B,C三个字段的值,再想把此dr导入 回A表, 故用了ImprotRow的方法,你说的ItemArray我现在试下。呵呵,谢谢了。