124

我正在寻找一种简单的方法来克隆 DataRow。有点像拍摄该行的快照并保存它。然后原始 Row 的值可以自由更改,但我们还有另一个未更改的保存副本。这是正确的方法吗?

DataRow Source, Destination;
// Assume we create some columns and fill them with values
Destination.ItemArray = Source.ItemArray;

这是否只是将 Snapshot 的 ItemArray 引用设置为指向 Source 中的引用,还是实际上制作了单独的副本?我应该这样做吗?

Destination.ItemArray = Source.ItemArray.Clone();

编辑:我认为第二个代码片段实际上并没有编译。

4

4 回答 4

198

您可以使用ImportRow方法将 Row 从 DataTable 复制到具有相同架构的 DataTable:

var row = SourceTable.Rows[RowNum];
DestinationTable.ImportRow(row);

更新:

通过您的新编辑,我相信:

var desRow = dataTable.NewRow();
var sourceRow = dataTable.Rows[rowNum];
desRow.ItemArray = sourceRow.ItemArray.Clone() as object[];

将工作

于 2012-08-19T07:54:26.510 回答
3

注意:cuongle 的 helfpul 答案包含所有要素,但可以简化解决方案(不需要.ItemArray),并且可以重新构建以更好地匹配所提出的问题。

要创建给定System.Data.DataRow实例的(隔离)克隆,您可以执行以下操作:

// Assume that variable `table` contains the source data table.

// Create an auxiliary, empty, column-structure-only clone of the source data table.
var tableAux = table.Clone();
// Note: .Copy(), by contrast, would clone the data rows also.

// Select the data row to clone, e.g. the 2nd one:
var row = table.Rows[1];

// Import the data row of interest into the aux. table.
// This creates a *shallow clone* of it.
// Note: If you'll be *reusing* the aux. table for single-row cloning later, call
//       tableAux.Clear() first.
tableAux.ImportRow(row);

// Extract the cloned row from the aux. table:
var rowClone = tableAux.Rows[0];

注意:执行克隆,它对作为值类型实例的列值按原样工作,但还需要做更多的工作来创建包含引用类型实例的列值的独立副本(并且创建这样的独立副本并不总是可能的)。

于 2019-11-11T16:38:07.290 回答
1

似乎您不想将整个 DataTable 保留为副本,因为您只需要一些行,对吗?如果您有一个 creteria,您可以在表上使用 select 指定,您可以将这些行复制到 DataRow 的额外备份数组中,例如

DataRow[] rows = sourceTable.Select("searchColumn = value");

.Select() 函数有几个选项,例如可以将这个选项读取为 SQL

SELECT * FROM sourceTable WHERE searchColumn = value;

然后您可以如上所述导入所需的行。

targetTable.ImportRows(rows[n])

...对于您喜欢的任何有效 n,但每个表中的列必须相同。

关于 ImportRow 你应该知道的一些事情是在使用主键时运行时会出现错误!

首先,我想检查是否已经存在由于缺少主键而失败的行,但是检查总是失败。最后我决定完全清除现有行并再次导入我想要的行。

第二个问题确实有助于理解发生了什么。我使用导入功能的方式是在一列中复制具有交换条目的行。我意识到它总是在变化,它仍然是对数组中行的引用。我首先必须导入原件,然后更改我想要的条目。

该参考资料还解释了当我第一次尝试导入该行时出现的主键错误,因为它实际上是加倍的。

于 2020-02-24T15:10:02.000 回答
-3

但要确保您的新行可以在新表中访问,您需要关闭该表:

DataTable destination = new DataTable(source.TableName);
destination = source.Clone();
DataRow sourceRow = source.Rows[0];
destination.ImportRow(sourceRow);
于 2015-04-04T19:03:02.220 回答