尝试添加行时,该行已属于另一个表错误?


196

我有一个包含一些行的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 2010年

Answers:


338

您需要Row使用第一个值创建一个新值dr。A DataRow只能属于一个DataTable

您还可以使用Add接受值数组:

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

3
嘿,我刚刚意识到ImportRow,编辑我的答案,你们都击败了我。但是,是的,我建议您采用这种方法,因为它将为您复制行
JoshBerke'2009年

2
ImportRowdin为我工作。但是添加行做到了!Thanksssssssssss
nawfal 2011年

1
如果您导入的行是对源表中该行的引用,则ImportRow将不起作用。如果使用源行,则ItemArray可以工作,但必须记住在从源中删除该行之前将其添加到目标中,否则它会抱怨该行已被删除并且找不到数据。
亚当·霍兹沃思

2
.ImportRow()最初对我不起作用,因为我没有.Clone()在新的DataTable上创建列或在其上创建列。当我在.Rows.Count新桌子上看时,它的值为0 。由于我需要在表上创建列并将其添加,因此我只创建了一条NewRow()语句,将值直接添加到该新行的列中,并将该行添加到我的表中(在循环内)(请参见下面的答案) 。
vapcguy

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
我也有一个错误的表。谢谢!
布鲁诺


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应该在这里是什么?
2014年

dtAvi中选定行的新DataTable 。
vapcguy

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.