DataRowをコピーまたは複製する簡単な方法は?


118

DataRowのクローンを作成する簡単な方法を探しています。そのロウのスナップショットを撮って保存するようなものです。元の行の値は自由に変更できますが、変更されていない別の保存されたコピーがあります。これは正しい方法ですか?

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

これは、スナップショットのItemArray参照をSourceの参照を指すように設定するだけですか、それとも実際に別のコピーを作成しますか?代わりにこれを行う必要がありますか?

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

編集:2番目のコードスニペットが実際にコンパイルされるとは思いません。


データ行を1つのテーブルから別のテーブルにコピーしますか?もしそうなら、私はDataTable.ImportRowを使用することがあなたが求めているものだと信じています。
Mo Patel 2012

わかりました。私の質問は今すぐ再作成する必要があります
ポールマシューズ

2
一部のシナリオでは、datarow自体がBeginEdit / EndEdit / CancelEditによるトランザクション編集をサポートしているため、これを行う必要がない場合があることに注意してください。また、その上で.RejectChangesを呼び出すことができます。
peterG 2014年

回答:


185

ImportRowメソッドを使用して、同じスキーマで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[];

動作します


どうやらClone()は浅いコピーのみを提供します。同じコピーを作成するのに十分でしょうか、それともディープクローンが必要ですか?
ポールマシューズ

5
@PaulMatthews:幸運なことに、DataTableには参照タイプではなく値タイプが含まれているため、値タイプの浅いコピーは深いコピーと同じです
cuongle

16
この投稿を見つけた人のために、よく聞かれるように以下を追加します。他の人が混乱しているのではないかと思います。構造のみを複製コピーし、構造をコピーしてからデータをコピーします。これは、両方のテーブルには、インスタンス化後にデータをコピーするには、別の簡単な方法は、先のテーブルに新しい行を作成し、以下を使用することであると述べている:destRow.ItemArray = sourceRow.ItemArrayと、単純な追加行バックdestTable.Rows.Add(destRow);
フランク

1
私はこの方法を使用して、データ行のクローンを取得しようとしています。次の手順を実行してから、ソース行を含むデータテーブルをクリアすると、空白のフィールドを持つソース行ができます。
SergеуIsupov

ImportRowメソッドを使用するとうまくいきましたが、NewRowメソッドではうまくいきませんでした。
OldDog 2017

2

注: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];

注:浅い複製が実行されます。これは、値型インスタンスである列値でそのまま機能しますが、参照型インスタンスを含む列値の独立したコピーを作成するには、さらに多くの作業が必要になります(そのような独立したコピーを作成することが常に可能であるとは限りません)。


1

いくつかの行しか必要ないため、DataTable全体をコピーとして保持したくないようです。テーブルの選択で指定できるクレテリアがあれば、それらの行だけをDataRowの追加のバックアップ配列にコピーできます。

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

.Select()関数にはいくつかのオプションがあり、これはたとえばSQLとして読み取ることができます

SELECT * FROM sourceTable WHERE searchColumn = value;

次に、上記のように必要な行をインポートできます。

targetTable.ImportRows(rows[n])

...任意の有効なnが必要ですが、列は各テーブルで同じである必要があります。

ImportRowについて知っておくべきいくつかのことは、主キーを使用するとランタイム中にエラーが発生することです!

まず、主キーがないために失敗した行がすでに存在しているかどうかを確認したかったのですが、その後、常に失敗しました。結局、既存の行を完全にクリアして、もう一度必要な行をインポートすることにしました。

2番目の問題は、何が起こるかを理解するのに役立ちました。インポート機能を使用する方法は、1つの列で交換されたエントリを持つ行を複製することです。それは常に変化し、それでも配列内の行への参照であることに気付きました。最初にオリジナルをインポートしてから、必要なエントリを変更する必要がありました。

リファレンスは、行が実際に2倍になったため、最初に行をインポートしようとしたときに発生した主キーエラーについても説明しています。


-4

ただし、新しいテーブルで新しい行にアクセスできるようにするには、テーブルを閉じる必要があります。

DataTable destination = new DataTable(source.TableName);
destination = source.Clone();
DataRow sourceRow = source.Rows[0];
destination.ImportRow(sourceRow);

3
コードの2行目が変数を再割り当てする場合、コードの1行目のポイントは何ですか?
エリックフィリップス

この回答はより多くの説明を使用する可能性があり(そして、テーブルを閉じる必要があるかわからない)、@ ErikPhilipsはポイント(すべき)を持ってDataTable destination = source.Clone()いますが、それ以外の場合、この回答は完全に問題なく.ItemArray、受け入れられた回答のアプローチよりも好ましいです。
mklement0
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.