全球声明的DataTable已经属于另一个DataSet

时间:2014-10-03 20:33:32

标签: c# datatable dataset

我在理解某些逻辑时遇到了问题,但我很高兴能够了解其中的内容。我有一个应用程序,它使用第三方Web服务来执行xml并接收响应,这里没有问题。我有一些全局声明的DataSet和DataTables。我这样做的原因是因为这些DataSet和DataTables不会改变,但需要从其他方法访问。会发生什么是表单加载,我的DataGridView填充得很好但是当我从myComboBox中选择一个不同的日期时,代码会抛出一个异常,说明DataTable已经属于另一个DataSet。以下是我正在使用的简化示例:

public class Test
{
  private BusinessLayer businessLayer;
  private int id;
  private List<int> employees;
  private DataSet employeeInfoDataSet;
  private DataSet employeesTimeDataSet;
  private DataTable employeeInfoDataTable;
  private DataTable employeesTimeDataTable;

  public Test()
  {
    businessLayer = new BusinessLayer();

    id = 3;

    // these should never change
    // I almost thought about making them static
    employees = businessLayer.getEmployees(id);
    employeeInfoDataSet = businessLayer.getEmployeeInfoDataSet(employees);
    employeeInfoDataTable = businessLayer.getEmployeeInfoDataTable(employeeInfoDataSet);
    employeeInfoDataTable.TableName = "EmployeeInfo";

    string date = myComboBox.SelectedValue.ToString();

    initDataTable(date);
    bindDataGridView();
  }

  private void initDataTable(string date)
  {
    employeesTimeDataSet = businessLayer.getEmployeesTime(employees, date);
    employeesTimeDataSet.Tables.Add(employeeInfoDataTable); // <-- errors here
    employeesTimeDataTable = businessLayer.buildEmployeesTimeDataTable(employeesTimeDataSet);
  }

  private void bindDataGridView()
  {
    dgv.DataSource = timesheetsDataTable;
  }

  private void myComboBox_SelectionChangeCommitted(object sender, EventArgs e)
  {
    string date = myComboBox.SelectedValue.ToString();
    initDataTable(date);
    bindDataGridView();
  }

}

我很难理解为什么它在表单加载时运行良好但在我更改日期时抛出此异常。有人能帮助我理解是什么导致了这个吗?很多,非常感谢!

PS:businessLayer.getEmployeeInfoDataTable和businessLayer.buildEmployeesTimeDataTable方法以编程方式构建DataTables,因此不应该出现需要使用DataTable.Copy()的“return ds.Tables [0]”问题...谢谢: )

1 个答案:

答案 0 :(得分:3)

错误信息不言自明,不是吗?您正尝试将同一个表添加到另一个DataSet中,您已将其添加到构造函数中的一个表中。您不能将同一个表(相同的引用)添加到两个不同的DataSets。那你想做什么?

  1. 也许你想检查它是否已经在DataSet

    if( employeeInfoDataTable.DataSet == null)
        employeesTimeDataSet.Tables.Add(employeeInfoDataTable);
    
  2. 如果可能,您可能希望首先将此表格包含在DataSet中,这似乎是最佳选择。

  3. 或者您可能希望在再次创建表之前从DataSet中删除该表。通过这种方式,表格的DataSet属性将被“清除”(您无法分配null),您可以稍后将表格添加到新创建的DataSet

    所以这样:

    private void initDataTable(string date)
    {
       employeesTimeDataSet.Tables.Remove(employeeInfoDataTable);
       employeesTimeDataSet = businessLayer.getEmployeesTime(employees, date);
       employeesTimeDataSet.Tables.Add(employeeInfoDataTable); // <-- now it works
       employeesTimeDataTable = businessLayer.buildEmployeesTimeDataTable(employeesTimeDataSet);
    }
    
  4. 请注意,如果您尝试将同一个表格两次添加到同一个DataSet,则此异常类似于引发的异常。两者都被检查,不被允许。