【问题标题】:This Row already belongs to another table error when trying to add rows?尝试添加行时,此行已属于另一个表错误?
【发布时间】:2010-10-17 20:21:13
【问题描述】:

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

【问题讨论】:

  • 好问题;我对属于其他容器的行和表感到困惑

标签: c#


【解决方案1】:

您需要先使用来自dr 的值创建一个新的Row。一个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);

【讨论】:

  • 我可以使用 ImportRow 作为替代方案吗?以及为什么 .NET 只不允许您为不同的 DataTables 使用相同的 DataRow?这是设计使然吗?
  • 嘿,我刚刚意识到 ImportRow,编辑我的答案,你们都打败了我。但是是的,我会推荐这种方法,因为它会为你复制行
  • ImportRow 为我工作。但是添加行做到了!谢谢sssssssssssssss
  • 如果您导入的行是对源表中行的引用,ImportRow 将不起作用。如果您使用源行,ItemArray 有效,但您必须记住在从源中删除行之前将该行添加到目标,否则它会抱怨该行已被删除并且找不到数据。
  • .ImportRow() 对我不起作用,因为我最初没有做.Clone() 或在我的新数据表上创建列。当我在我的新桌子上查看.Rows.Count 时,它得出了 0。因为我需要在我的表上创建列并添加它们,所以我只是创建了一个 NewRow() 语句并将我的值直接添加到该新行上的列中,并将该行添加到我的表中,在循环中(请参阅我的在下面回答)。
【解决方案2】:

试试这个:

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

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

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

【讨论】:

  • 谢谢您。尽管@JoshBerke 提供的答案是正确的,但您需要像示例中那样克隆原始表才能正常工作。
【解决方案3】:
yourTable.ImportRow(dataRow);

这是因为你正在复制的行没有相同的TableName

例如,试试:

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

【讨论】:

  • 我也有一个错误命名的表。谢谢!
【解决方案4】:
foreach (DataRow dr in dtSpecificOrders.rows)
{
   dtSpecificOrders.Rows.Add(dr.ItemArray); 
}

【讨论】:

  • 我不认为你可以在你正在迭代的内容中添加任何东西,因为你正在迭代它。
  • IMO,这是此页面上最重要的答案。假设您要更改一个字段的值,然后添加另一条所有其他字段相同的记录。如果您使用 dt.NewRow 它将清除项目数组。许多帖子建议您克隆数据表和行以保留值,但如果您使用这种形式的 Rows.Add 方法,则没有必要这样做。否则,您需要 dt.AcceptChanges() 方法,所有这些都可以通过七年前发布的这一行简单、完美的代码来避免。我在其他任何地方都找不到这个答案。
【解决方案5】:

这不是最干净/最快/最简单/最优雅的解决方案,但它是我为在类似情况下完成工作而创建的蛮力解决方案:

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”和“Name”为例。

【讨论】:

    【解决方案6】:

    你为什么不直接使用CopyToDataTable

    DataTable dt = (DataTable)Session["dtAllOrders"];
    DataTable dtSpecificOrders = new DataTable();
    
    DataTable orderRows = dt.Select("CustomerID = 2").CopyToDataTable();
    

    【讨论】:

    • orderRows 应该是什么?
    • 来自dt, Avi 的选定行的新数据表。
    【解决方案7】:

    您可以为列指定一些 id 并为其命名。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-18
      相关资源
      最近更新 更多