- •А.А. Волосевич
- •4. БАзы данных и технология ado.Net 3
- •4. БАзы данных и технология ado.Net
- •4.1. Архитектура ado.Net
- •4.2. Соединение с базой данных
- •4.3. Выполнение команд и запросов к базе данных
- •4.4. Параметризированные запросы
- •4.5. Чтение данных и объект DataReader
- •4.6. Рассоединенный набор данных
- •4.7. Объект класса DataColumn – колонка таблицы
- •4.8. Объекты класса DataRow – строки таблицы
- •4.9. Работа с объектом класса DataTable
- •4.10. Схема данных и типизированные dataset
- •4.11. Навигация, Поиск и фильтрация данных в DataSet
- •4.12. Класс DataView
- •4.13. Заполнение Рассоединенного набора данных
- •4.14. СиНхронизация набора данных и базы
- •4.15. Работа с транзакциями
4.9. Работа с объектом класса DataTable
Любой рассоединенный набор данных содержит одну или несколько таблиц. В данном параграфе рассматривается настройка отдельной таблицы, ее свойства и методы.
Наиболее важные свойства класса DataTable приведены в табл. 9.
Таблица 9
Свойства класса DataTable
Имя свойства |
Описание |
CaseSensitive |
Определяет, учитывается ли регистр при поиске строк в таблице (по умолчанию false – не учитывается) |
ChildRelations |
Возвращает коллекцию подчиненных связей для таблицы |
Columns |
Набор столбцов таблицы |
Constraints |
Набор ограничений, заданных для таблицы |
DataSet |
Рассоединенный набор данных, включающий таблицу |
DefaultView |
Указывает на представление по умолчанию (DataView) для таблицы |
ExtendedProperties |
Коллекция пользовательских свойств таблицы |
HasErrors |
Указывает, содержит ли таблица ошибки |
Locale |
Свойство имеет тип CultureInfo и определяет региональные параметры, используемые таблицей при сравнении строк |
MinimumCapacity |
Служит для получения или установки исходного количества строк таблицы (по умолчанию – 25 строк) |
ParentRelations |
Коллекция родительских отношений для таблицы |
PrimaryKey |
Массив столбцов, формирующих первичный ключ таблицы |
RemotingFormat |
Позволяет указать формат данных при сериализации объекта – бинарный или XML |
Rows |
Набор строк таблицы |
TableName |
Строка с именем таблицы |
Если требуется вручную создать таблицу, то можно воспользоваться конструктором класса DataTable. Конструктор имеет перегруженную версию, которая позволяет установить имя таблицы – свойство TableName:
var dataTable = new DataTable("Main Table");
Работа со свойствами таблицы Columns и Rows обсуждалась ранее. Свойства ChildRelations, ParentRelations, Constraints и PrimaryKey будут рассмотрены в следующем параграфе. При помощи свойства DataSet таблица связывается с определенным набором данных.
Кроме набора свойств, класс DataTable обладает следующими методами, перечисленными в табл. 10.
Таблица 10
Методы класса DataTable
Имя метода |
Описание |
AcceptChanges() |
Метод фиксирует все изменения данных в строках таблицы, которые были проделаны с момента предыдущего вызова AcceptChanges() |
BeginLoadData() |
Отключает все ограничения при загрузке данных |
Clear() |
Уничтожаются все строки таблицы |
Clone() |
Метод клонирует структуру таблицы и возвращает таблицу без строк |
Compute() |
Метод применяет строку-выражение, заданную в качестве параметра, к диапазону строк таблицы |
Copy() |
Метод клонирует и структуру, и данные таблицы |
EndLoadData() |
Активирует ограничения после загрузки данных |
GetChanges() |
Метод возвращает таблицу с идентичной схемой, содержащую изменения, которые еще не зафиксированы методом AcceptChanges() |
GetErrors() |
Возвращает массив объектов DataRow, которые нарушают ограничения таблицы |
ImportRow() |
В таблицу вставляется строка, указанная в качестве параметра |
LoadDataRow() |
Добавляет или обновляет строку таблицы, основываясь на содержимом массива-параметра |
NewRow() |
Создается пустая строка по схеме столбцов таблицы |
RejectChanges() |
Метод отменяет изменения, которые еще не зафиксированы вызовом AcceptChanges() |
Reset() |
Восстанавливает оригинальное состояние объекта DataTable, в котором он находился до инициализации |
Select() |
Возвращает массив строк таблицы на основании заданного критерия поиска |
ReadXml() |
Читает содержимое DataTable в XML-формате из файла, Stream, TextReader или XmlReader |
ReadXmlSchema() |
Работает как ReadXml(), но читает только схему DataTable |
WriteXml() |
Записывает содержимое DataTable в XML-формате в файл, Stream, TextWriter или XmlWriter |
WriteXmlSchema() |
Работает как WriteXml(), но записывает только схему таблицы |
Рассмотрим некоторые методы таблицы подробнее. Если в таблицу добавляется группа строк (объектов DataRow), то для повышения производительности кода следует применить методы BeginLoadData() и EndLoadData(). При вызове метода BeginLoadData() отключаются определенные на таблице ограничения. Активировать их можно, вызвав метод EndLoadData(). Если в таблице есть строки, нарушающие какие-либо ограничения, при вызове метода EndLoadData() генерируется исключение ConstraintException. Чтобы определить, какие именно строки нарушают ограничения, следует просмотреть массив, возвращаемый методом GetErrors().
Метод Clear() позволяет удалить из таблицы все строки. Вызвать его быстрее, чем освободить оригинальный и создать новый объект DataTable с идентичной структурой.
Метод Compute() позволяет выполнять агрегатные запросы к отдельным столбцам таблицы на основе заданных критериев поиска. Метод принимает два строковых параметра. Первый содержит выражение для вычисления1, второй является фильтром, отбирающим некий диапазон строк таблицы. Следующий пример кода загружает из базы CD_Rent таблицу Rent и вычисляет средний рейтинг диска с disk_id = 1:
var da = new SqlDataAdapter("SELECT * FROM Rent", "Server=...");
var rentTable = new DataTable("Rent");
da.Fill(rentTable);
var rent = (double)rentTable.Compute("Avg(rating)", "disk_id = 1"));
Группа методов используется для добавления в таблицу новых строк. Метод таблицы ImportRow() принимает объект-строку и добавляет его в таблицу. Метод LoadDataRow() принимает в качестве первого аргумента массив, элементы которого соответствуют элементам коллекции Columns таблицы. Метод пытается найти в таблице строку, соответствующую своему первому аргументу и обновить её. Если строка не найдена, она создается. Второй аргумент метода LoadDataRow() – это логическое значение, управляющее свойством RowState нового объекта DataRow. Чтобы задать свойству RowState значение Added, передайте в качестве второго аргумента false; если необходимо задать значение Unmodified, передайте true. Метод LoadDataRow() возвращает ссылку на созданную или найденную строку. Метод NewRow() возвращает для таблицы новую строку, но не добавляет его в коллекцию Rows таблицы. Добавление следует осуществить вручную, предварительно заполнив необходимые поля строки. Рекомендуется следующее:
-
Для импорта строки из сторонней таблицы используйте метод ImportRow().
-
Для одновременного импорта нескольких строк, например на основе содержимого файла, применяйте метод LoadDataRow(). Это позволит вам писать меньше кода, чем при работе с методом NewRow().
-
Во всех остальных случаях вызывайте метод NewRow().
Любая таблица поддерживает следующий набор событий:
-
ColumnChanged – происходит после изменения содержимого поля некой строки;
-
ColumnChanging – перед изменением содержимого поля строки;
-
RowChanged – происходит после изменения содержимого строки;
-
RowChanging – генерируется перед изменением содержимого строки;
-
RowDeleted – происходит после удаления строки;
-
RowDeleting – происходит перед удалением строки.
События ColumnChanged и ColumnChanging наступают каждый раз, когда изменяется содержимое одного из полей строки. Они позволяют осуществлять проверку данных, активировать и деактивировать элементы управления, и т.д. У событий есть аргумент типа DataColumnChangeEventArgs, обладающий свойствами Row и Column, которые позволяют определить, какие именно поле и строка изменены. Помните: при использовании данных событий для редактирования содержимого строки иногда возникает замкнутый цикл.
События RowChanged и RowChanging наступают каждый раз, когда изменяется содержимое строки или значение свойства RowState строки. Чтобы определить, почему наступило событие, достаточно просмотреть значение свойства Action аргумента DataColumnChangeEventArgs этого события. Свойство Row указанного аргумента позволяет обращаться к изменяемой записи.
События RowDeleted и RowDeleting предоставляют такие же аргументы и свойства, как события RowChanged и RowChanging. Единственное отличие в том, что данные события наступают при удалении строки из таблицы.