DataRow

30

Мы видели, что коллекция объектов DataColumn представляет схему объекта DataTable. А коллекция объектов DataRow представляет конкретные данные в таблице. И если на складе имеются 20 автомобилей, то для хранения информации о них нужно 20 объектов DataRow. Некоторые (но не все) члены класса DataRow перечислены ниже:

HasErrors, GetColumnsInError(), GetColumnError(), ClearErrors(), RowError

Свойство HasErrors возвращает логическое значение, означающее наличие ошибок. Если они есть, то метод GetColumnsInError() позволяет получить ошибочные столбцы, а метод GetColumnError() — получить описание ошибки. Аналогично, метод ClearErrors() удаляет из строки всю информацию об ошибках. Свойство RowError позволяет создать текстовое описание ошибки для данной строки

ItemArray

Свойство, задающее или получающее все значения столбцов строки в виде массива объектов

RowState

Свойство, позволяющее зафиксировать текущее состояние объекта DataRow в содержащем его DataTable с помощью значений перечисления RowState (новый, измененный, не измененный или удаленный)

Table

Свойство, позволяющее получить ссылку на объект DataTable, содержащий данный объект DataRow

AcceptChanges(), RejectChanges()

Методы для фиксации или отмены всех изменений, выполненных в данной строке с момента последнего вызова AcceptChanges()

BeginEdit(), EndEdit(), CancelEdit()

Методы, начинающие, заканчивающие или отменяющие операцию редактирования для объекта DataRow

Delete()

Метод, помечающий данную строку для удаления при вызове метода AcceptChanges()

IsNull()

Метод, получающий значение, которое указывает, содержит ли заданный столбец пустое значение

Работа с объектами DataRow несколько отличается от работы с DataColumn: невозможно напрямую создать экземпляр данного типа, т.к. у него нет общедоступного конструктора:

// Ошибка! Нет общедоступного конструктора!
DataRow dr = new DataRow();

Вместо этого новый объект DataRow можно получить из конкретного DataTable. Предположим, например, что в таблицу Inventory нужно вставить две строки. Метод DataTable.NewRow() позволяет получить очередное место в таблице, после чего можно заполнить каждый столбец с помощью индексатора типа. При этом можно указать либо строковое имя, присвоенное объекту DataColumn, либо номер его позиции (начиная с нуля):

// Добавление строк в таблицу Inventory
            DataRow carRow = inventoryTable.NewRow();
            carRow["Make"] = "BMW";
            carRow["Color"] = "Black";
            carRow["PetName"] = "Hamlet";
            inventoryTable.Rows.Add(carRow);

            carRow = inventoryTable.NewRow();
            carRow[1] = "Saab";
            carRow[2] = "Red";
            carRow[3] = "Sea Breeze";
            inventoryTable.Rows.Add(carRow);

Если передать методу индексатора типа DataRow неверное имя столбца или позицию, будет сгенерировано исключение времени выполнения.

Теперь у вас есть один объект DataTable, содержащий две строки. Конечно, этот общий процесс можно повторить, чтобы создать ряд объектов DataTable, определить их схемы и заполнить данными. Но прежде чем вставить объект inventoryTable в объект DataSet, необходимо разобраться с очень важным свойством RowState.

Свойство RowState

Свойство RowState применяется для программной идентификации множества всех строк таблицы, которые изменили свое первоначальное значение, были вставлены и т.п. Это свойство может принимать любое значение из перечисления DataRowState:

Перечисление DataRowState
Значение Назначение
Added Строка была добавлена в DataRowCollection, a AcceptChanges() еще не был вызван
Deleted Строка была помечена для удаления с помощью метода Delete() класса DataRow, a AcceptChanges() еще не был вызван
Detached Строка была создана, но не включена ни в какой DataRowCollection. Объект DataRow находится в этом состоянии после его создания, но до занесения в какую-либо коллекцию, либо после исключения из коллекции
Modified Строка была изменена, a AcceptChanges() еще не был вызван
Unchanged Строка не была изменена после последнего вызова AcceptChanges()

При программной работе со строками объекта DataTable значения в свойство RowState заносятся автоматически. Объект ADO.NET DataRow вполне разумно отслеживает свое состояние. Поэтому владеющий этим объектом объект DataTable может определить добавленные, измененные или удаленные строки. Это очень важная возможность DataSet, потому что когда наступит время послать информацию в хранилище данных, будут отправлены только измененные данные.

Свойство DataRowVersion

Кроме отслеживания текущего состояния строк с помощью свойства RowState, объект DataRow отслеживает три возможные версии содержащихся в нем данных с помощью свойства DataRowVersion. При первоначальном создании объект DataRow содержит лишь одну копию данных, которая считается "текущей версией". Но при программной работе с объектом DataRow (с помощью вызовов различных методов) появляются дополнительные версии данных. Конкретнее, свойство DataRowVersion может содержать любое значение соответствующего перечисления DataRowVersion:

Перечисление DataRowVersion
Значение Назначение
Current Представляет текущее значение строки, даже после выполнения изменений
Default Стандартный вариант DataRowState. Если значение DataRowState равно Added, Modified или Deleted, то стандартной версией является Current. Для значения DataRowState, равного Detached, стандартной версией является Proposed
Original Представляет значение, первоначально вставленное в DataRow, или значение при последнем вызове AcceptChanges()
Proposed Значение строки, редактируемой в настоящий момент с помощью вызова BeginEdit()

Как показано в таблице, значение свойства DataRowVersion в большинстве случаев зависит от значения свойства DataRowState. А как было сказано ранее, значение свойства DataRowState автоматически изменяется при вызовах различных методов объекта DataRow (а в некоторых случаях DataTable). Ниже представлена схема влияния этих методов на значение свойства DataRowVersion произвольной строки:

Да, все это несколько запутанно — особенно из-за того, что в любой данный момент времени DataRow может иметь, а может и не иметь все версии (при попытке получения версии строки, которая в данный момент не отслеживается, возникнут исключения времени выполнения). Но поскольку DataRow отслеживает три копии данных, то, несмотря на эту сложность, можно без особого труда создать пользовательский интерфейс, который позволяет конечному пользователю изменить значения, потом передумать и отказаться от этих изменений или зафиксировать их, чтобы они хранились постоянно.

Пройди тесты
Лучший чат для C# программистов