この行は、行を追加しようとしたときにすでに別のテーブルエラーに属していますか?


197

いくつかの行があるDataTableがあり、selectを使用して行をフィルター処理してDataRowsのコレクションを取得し、foreachを使用してループして別のDataTableに追加しますが、「この行は既に属しています別のテーブルへ」これがコードです:

DataTable dt = (DataTable)Session["dtAllOrders"];
DataTable dtSpecificOrders = new DataTable();

DataRow[] orderRows = dt.Select("CustomerID = 2");

foreach (DataRow dr in orderRows)
{
    dtSpecificOrders.Rows.Add(dr); //Error thrown here.
}

1
すばらしい質問です。他のコンテナに属する行とテーブルについて混乱する
Vivian River

回答:


339

最初Rowからの値で新しいを作成する必要がありますdrDataRow一つだけに属することができますDataTable

Add値の配列を取るwhichを使用することもできます。

myTable.Rows.Add(dr.ItemArray)

またはおそらくさらに良い:

// This works because the row was added to the original table.
myTable.ImportRow(dr);

// The following won't work. No data will be added or exception thrown.
var drFail = dt.NewRow()
drFail["CustomerID"] = "[Your data here]";
// dt.Rows.Add(row); // Uncomment for import to succeed.
myTable.ImportRow(drFail);

6
ImportRowを代替として使用できますか?なぜ.NETでは、異なるDataTableに対して同じDataRowしか許可されないのですか?これは仕様ですか?
Xaisoft 2009

3
Heh私はImportRowに気づき、私の答えを編集しました。しかし、
そうですね。

2
ImportRow私のために仕事をします。しかし、行の追加は行いました!Thankssssssssssss
nawfal

1
インポートする行がソーステーブルの行への参照である場合、ImportRowは機能しません。ソース行を使用する場合、ItemArrayは機能しますが、ソースから行を削除する前に、行を宛先に追加する必要があります。そうしないと、行が削除されてデータが見つからないというメッセージが表示されます。
アダムホールズワース

2
.ImportRow().Clone()新しいDataTableで列を作成または作成しなかったため、最初は機能しませんでした。.Rows.Count新しいテーブルを見ると、0 でした。テーブルに列を作成して追加する必要があるため、NewRow()ステートメントを作成し、値をその新しい行の列に直接追加し、ループ内でその行をテーブルに追加しました(以下の私の回答を参照) 。
vapcguy 2016年

34

これを試して:

DataTable dt = (DataTable)Session["dtAllOrders"];
DataTable dtSpecificOrders = dt.Clone();

DataRow[] orderRows = dt.Select("CustomerID = 2");

foreach (DataRow dr in orderRows)
{
    dtSpecificOrders.ImportRow(dr);
}

3
これをありがとう.. @JoshBerkeによって提供された答えは正しかったが、それが機能するためには、例のように元のテーブルを複製する必要があります。
carny666

8
yourTable.ImportRow(dataRow);

これは、コピーしている行が同じではないためですTableName

たとえば、次のことを試してください。

Table1.TableName = "Table1";
Table2.TableName = "Table2";

1
テーブルの名前も間違っていました。ありがとう!
Bruno

3
foreach (DataRow dr in dtSpecificOrders.rows)
{
   dtSpecificOrders.Rows.Add(dr.ItemArray); 
}

1
反復しているので、反復しているものに何かを追加することはできないと思います。
vapcguy

3

これは最もクリーン/クイック/イージー/最もエレガントなソリューションではありませんが、同様のシナリオでジョブを実行するために私が作成したブルートフォースソリューションです。

DataTable dt = (DataTable)Session["dtAllOrders"];
DataTable dtSpecificOrders = new DataTable();

// Create new DataColumns for dtSpecificOrders that are the same as in "dt"
DataColumn dcID = new DataColumn("ID", typeof(int));
DataColumn dcName = new DataColumn("Name", typeof(string));
dtSpecificOrders.Columns.Add(dtID);
dtSpecificOrders.Columns.Add(dcName);

DataRow[] orderRows = dt.Select("CustomerID = 2");

foreach (DataRow dr in orderRows)
{
    DataRow myRow = dtSpecificOrders.NewRow();  // <-- create a brand-new row
    myRow[dcID] = int.Parse(dr["ID"]);
    myRow[dcName] = dr["Name"].ToString();
    dtSpecificOrders.Rows.Add(myRow);   // <-- this will add the new row
}

DataColumnsの名前は、元のテーブルの名前と一致する必要があります。例として「ID」と「名前」を使用しました。


1

使ってみませんか CopyToDataTable

DataTable dt = (DataTable)Session["dtAllOrders"];
DataTable dtSpecificOrders = new DataTable();

DataTable orderRows = dt.Select("CustomerID = 2").CopyToDataTable();

1
ここにあるはずのorderRowsは何ですか?
Avi

から選択された行の新しいDataTable dt、Avi。
vapcguy

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.