【问题标题】:This Row Already Belongs To This Table此行已属于此表
【发布时间】:2012-08-15 06:25:00
【问题描述】:

我从以下代码中收到错误“此行已属于此表”:

public static DataTable AddNewAllocations(string pCaseNo, ref DataTable pTable)
    {
        try
        {
            string sqlText = "SELECT UserID FROM tblUsers;";
            aSqlQuery aQ = new aSqlQuery(sqlText, "table");
            DataTable userTable = aQ.TableResult;

            foreach (DataRow userRow in userTable.Rows)
            {
                int allocAlready = 0;
                foreach (DataRow allocRow in pTable.Rows)
                {
                    if (allocRow["FeeEarner"].ToString() == userRow["UserID"].ToString())
                    {
                        allocAlready = 1;                            
                    }
                }
                if (allocAlready == 0)
                {
                    string strUser = userRow["UserID"].ToString();          
                    decimal fees = cTimesheet.UserFees(strUser, pCaseNo);
                    int intCaseNo = Int32.Parse(pCaseNo);
                    if (fees > 0)
                    {
                        Object[] array = new object[8];
                        array[0] = 0;
                        array[1] = intCaseNo;
                        array[2] = DateTime.Today;
                        array[3] = strUser;
                        array[4] = fees;
                        array[5] = 0;
                        array[6] = fees;
                        array[7] = true;
                        pTable.Rows.Add(array);
                    }
                }
            }
            return pTable;
        }

        catch (Exception eX)
        {
            throw new Exception("cAllocation: Error in NewAllocations()" + Environment.NewLine + eX.Message);
        }

当我单步执行代码时,我可以看到第二次抛出错误,访问以下行:

pTable.Rows.Add(array);

鉴于每次代码进入循环时我都会创建一个新的对象数组,我无法理解为什么我会收到此错误消息,这表明我正在多次添加同一行。为什么每次循环都是由新的对象数组生成行时,每次循环都添加了相同的数据行?

【问题讨论】:

  • 表中有主键吗?
  • 它是一个断开连接的表 - 但不是 - 我没有指定任何列作为主键 - 是这个问题吗?
  • 也许吧。尝试每次输入不同的值,看看是哪个字段导致的
  • 你不用换行吗?像 DataRow DR = pTable.NewRow();在你可以添加一行之前?
  • 请问这个是怎么回事?

标签: c# ado.net


【解决方案1】:

另一种方法是在循环开始时创建一个 NewRow(),分配其数据,然后在循环底部创建 Rows.Add()。

{       
        // initialization code 
        // ...

        foreach (DataRow row in dt.Rows)
        {
            row.Delete();
        }
        Oda.Update(ds, "USERTABLE");

        DataRow  dr;

        foreach (var userRecord in urList)
        {
            dr = dt.NewRow();
            dr["username"] = userRecord.userName;
            dr["firstname"] = userRecord.firstName;
            dr["lastname"] = userRecord.lastName;
            dr["createdon"] = userRecord.createdOn;

            dt.Rows.Add(dr);
        }
        Oda.Update(ds, "USERTABLE");
}

【讨论】:

  • 这个答案帮助我理解了我的错误。我在foreach 循环之前声明了新行dr = td.NewRow();。在循环内移动声明解决了我的问题。
【解决方案2】:

最终起作用的代码是这样的:

public static DataTable AddNewAllocations(string pCaseNo, DataTable pTable)
    {
        try
        {
            DataTable newTable = NewAllocationTable(); 

            string sqlText = "SELECT UserID FROM tblUsers;";
            aSqlQuery aQ = new aSqlQuery(sqlText, "table");
            DataTable userTable = aQ.TableResult;

            foreach (DataRow userRow in userTable.Rows)
            {
                int allocAlready = 0;
                foreach (DataRow allocRow in pTable.Rows)
                {
                    if (allocRow["FeeEarner"].ToString() == userRow["UserID"].ToString())
                    {
                        allocAlready = 1;                            
                    }
                }

                if (allocAlready == 0)
                {
                    string strUser = userRow["UserID"].ToString();          
                    decimal fees = cTimesheet.UserFees(strUser, pCaseNo);
                    int intCaseNo = Int32.Parse(pCaseNo);
                    if (fees > 0)
                    {
                        Object[] array = new object[8];
                        array[0] = 0;
                        array[1] = intCaseNo;
                        array[2] = DateTime.Today;
                        array[3] = strUser;
                        array[4] = fees;
                        array[5] = 0;
                        array[6] = fees;
                        array[7] = true;
                        newTable.Rows.Add(array);
                    }
                }
            }

            foreach (DataRow row in pTable.Rows)
            {
                newTable.ImportRow(row);
            }

            newTable.DefaultView.Sort = "AllocID";
            return newTable;
        }

        catch (Exception eX)
        {
            throw new Exception("cAllocation: Error in NewAllocations()" + Environment.NewLine + eX.Message);
        }
    }

我认为关键是使用 ImportRow 而不是 Rows.Add。我仍然在我的方法中使用 Rows.Add,但仅在将行添加到新创建的表时。然后,我遍历作为参数传入的现有表,并使用 ImportRow 将参数表的每一行添加到新创建的表中。然后,我在我的 return 语句中传递新的组合表,而不是修改后的参数表。

【讨论】:

    猜你喜欢
    • 2012-03-11
    • 2010-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多