ReadOnlyException DataTable DataRow «Столбец X доступен только для чтения».

У меня есть небольшой фрагмент кода, который изначально создавал объект SqlDataAdapter снова и снова.

Пытаясь немного упростить мои звонки, Я заменил SqlDataAdapter на SqlCommand и переместил SqlConnection за пределы цикла.

Теперь, когда я пытаюсь редактировать строки данных, возвращаемых в мой DataTable , я получаю исключение ReadOnlyException , которое не создавалось ранее.

ПРИМЕЧАНИЕ. У меня есть настраиваемая функция, которая извлекает полное имя сотрудника на основе его идентификатора. Для простоты я использовал «John Doe» в приведенном ниже примере кода, чтобы продемонстрировать свою точку зрения.

ExampleQueryOld работает с SqlDataAdapter ; ExampleQueryNew завершается ошибкой ReadOnlyException всякий раз, когда я пытаюсь записать в элемент DataRow :

  • ExampleQueryOld

Это работает и не имеет проблем:

public static DataTable ExampleQueryOld(string targetItem, string[] sqlQueryStrings) {
  DataTable bigTable = new DataTable();
  for (int i = 0; i < sqlQueryStrings.Length; i++) {
    string sqlText = sqlQueryStrings[i];
    DataTable data = new DataTable(targetItem);
    using (SqlDataAdapter da = new SqlDataAdapter(sqlText, Global.Data.Connection)) {
      try {
        da.Fill(data);
      } catch (Exception err) {
        Global.LogError(_CODEFILE, err);
      }
    }
    int rowCount = data.Rows.Count;
    if (0 < rowCount) {
      int index = data.Columns.IndexOf(GSTR.Employee);
      for (int j = 0; j < rowCount; j++) {
        DataRow row = data.Rows[j];
        row[index] = "John Doe"; // This Version Works
      }
      bigTable.Merge(data);
    }
  }
  return bigTable;
}
  • ExampleQueryNew

В этом примере создается исключение ReadOnlyException:

public static DataTable ExampleQueryNew(string targetItem, string[] sqlQueryStrings) {
  DataTable bigTable = new DataTable();
  using (SqlConnection conn = Global.Data.Connection) {
    for (int i = 0; i < sqlQueryStrings.Length; i++) {
      string sqlText = sqlQueryStrings[i];
      using (SqlCommand cmd = new SqlCommand(sqlText, conn)) {
        DataTable data = new DataTable(targetItem);
        try {
          if (cmd.Connection.State == ConnectionState.Closed) {
            cmd.Connection.Open();
          }
          using (SqlDataReader reader = cmd.ExecuteReader()) {
            data.Load(reader);
          }
        } catch (Exception err) {
          Global.LogError(_CODEFILE, err);
        } finally {
          if ((cmd.Connection.State & ConnectionState.Open) != 0) {
            cmd.Connection.Close();
          }
        }
        int rowCount = data.Rows.Count;
        if (0 < rowCount) {
          int index = data.Columns.IndexOf(GSTR.Employee);
          for (int j = 0; j < rowCount; j++) {
            DataRow row = data.Rows[j];
            try {
              // ReadOnlyException thrown below: "Column 'index'  is read only."
              row[index] = "John Doe";
            } catch (ReadOnlyException roErr) {
              Console.WriteLine(roErr.Message);
            }
          }
          bigTable.Merge(data);
        }
      }
    }
  }
  return bigTable;
}

Почему я могу писать в элемент DataRow в одном случае, но не в другом?

Это потому, что SqlConnection все еще открыт или SqlDataAdapter что-то делает за кулисами?

44
задан jp2code 25 March 2011 в 15:49
поделиться