- •А.А. Волосевич
- •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.12. Класс DataView
Метод DataTable.Select() – очень мощный и гибкий, но не является оптимальным решением для всех ситуаций. Этот метод принимает динамические критерии поиска и поэтому не может быть сверхэффективным. В ADO.NET предусмотрен специальный класс для фильтрации, сортировки и поиска в содержимом таблиц. Это класс DataView.
Объекты DataView не являются SQL-запросами, в отличие от представлений (view) в базах данных. С помощью DataView нельзя объединить данные двух таблиц, равно как и просмотреть отдельные столбцы таблицы. Объекты DataView поддерживают фильтрацию запросов на основе динамических критериев, но разрешают обращаться только к одному объекту DataTable; кроме того, через DataView всегда доступны все столбцы таблицы. У объекта DataView нет собственной копии данных. При обращении через DataView к данным он возвращает записи, хранящиеся в соответствующем объекте DataTable.
Чтобы просмотреть с помощью объекта DataView данные некоторой таблицы, его следует связать с этой таблицей. Есть два способа сделать это: используя свойство Table объекта DataView или при помощи конструктора DataView. У DataView также есть конструктор, сигнатура которого более точно соответствует методу DataTable.Select(). Этот конструктор задает значения свойств Table, RowFilter, Sort и RowStateFilter объекта DataView в одной строке кода. Следующие варианты кода эквивалентны:
var dt = CD_Rent.Tables["Disks"];
// первый вариант
var dv = new DataView();
dv.Table = dt;
dv.RowFilter = "release_year = 2005";
dv.Sort = "title DESC";
dv.RowStateFilter = DataViewRowState.ModifiedOriginal;
// Второй вариант
var dv1 = new DataView(dt, "release_year = 2005", "title DESC",
DataViewRowState.ModifiedOriginal);
Свойство RowStateFilter принимает значения из перечисления DataViewRowState. Это перечисление можно рассматривать как комбинацию свойства RowState объекта DataRow и перечисления DataRowVersion.
-
Added – отображаются добавленные строки;
-
CurrentRows – отображаются строки, которые не были удалены (значение по умолчанию);
-
Deleted – отображаются удаленные строки;
-
ModifiedCurrent – отображаются измененные строки с их текущими значениями;
-
ModifiedOriginal – отображаются измененные строки с их оригинальными значениями;
-
None – строки не отображаются;
-
OriginalRows – отображаются удаленные, измененные и не изменявшиеся строки с их оригинальными значениями;
-
Unchanged – отображаются строки, которые не изменялись.
Свойство RowStateFilter работает в качестве двойного фильтра. Например, если задать ему значение ModifiedOriginal, через объект DataView окажутся доступны только измененные записи, и вы будете видеть их оригинальные значения.
Объект DataView возвращает данные с помощью собственного специализированного объекта – DataRowView. Функциональность DataRowView в целом аналогична функциональности DataRow. DataRowView обладает свойством Item, позволяющим обращаться к содержимому поля как по имени, так и по порядковому номеру. И хотя свойство Item разрешает просматривать и изменять содержимое поля, через DataRowView доступна только одна версия данных строки – та, которая указана при помощи свойства DataRowVersion. Если объект DataRowView не обеспечивает требуемых возможностей, обратитесь при помощи свойства Row этого объекта к соответствующему объекту DataRow из таблицы.
Доступ к данным объекта DataTable при помощи DataView осуществляется иначе, чем непосредственный доступ к объекту DataTable. Таблица предоставляет свои строки через свойство Rows. У DataView нет похожего, допускающего простое перечисление, набора. DataView имеет свойство Count, возвращающее число строк, и индексатор Item с целым индексом. Используя эти свойства, можно создать простой цикл для просмотра всех строк:
var dv = new DataView(dt, "id > 10", "title DESC",
DataViewRowState.CurrentRows);
foreach (DataRowView drv in dv)
{
Console.WriteLine(drv["title"]);
}
Класс DataView предоставляет методы Find() и FindRows(), позволяющие искать в нем данные. Эти методы аналогичны методу Find() коллекции Rows таблицы. Задав значение свойства Sort объекта DataView, вы получите возможность с помощью метода Find() искать строки по значениям столбцов, перечисленных в свойстве Sort. Как и в случае с методом DataRowCollection.Find(), одноименному методу DataView разрешено передавать одно значение или массив значений. Тем не менее, метод DataView.Find() возвращает не объект DataRow или DataRowView, а значение целого типа, соответствующее порядковому номеру нужной строки в объекте DataView. Если искомая строка не найдена, метод вернет -1:
var dt = CD_Rent.Tables["Disks"];
var dv = new DataView(dt)
{ RowFilter = "release_year = 2005", Sort = "title" };
var findIndex = dv.Find("Mezmerize");
if (findIndex != -1)
{
Console.WriteLine(dv[findIndex]["artist_id"]);
}
Метод DataView.Find() осуществляет поиск по столбцам, указанным в свойстве Sort. У многих строк могут быть одинаковые значения полей, используемых для сортировки данных. Например, при сортировке дисков по полю release_year это поле может иметь значение "2005" для нескольких строк. Тем не менее, найти посредством метода Find() все диски, выпущенные в 2005 году нельзя, поскольку он возвращает только одно целочисленное значение. К счастью, класс DataView предоставляет метод FindRows(). Его вызывают так же, как и метод Find(), но метод FindRows() возвращает массив объектов DataRowView, содержащих строки, которые удовлетворяют критериям поиска.
var dt = CD_Rent.Tables["Disks"];
var dv = new DataView(dt)
{ RowFilter = "release_year = 2005", Sort = "release_year" };
DataRowView[] res = dv.FindRows("2005");
if (res.Length != 0)
{
Console.WriteLine("Find {0} rows", res.Length);
}
Строка данных модифицируется с помощью объекта DataRowView аналогично изменению содержимого объекта DataRow. Создание новой строки данных при помощи объекта DataRowView несколько отличается от создания нового объекта DataRow. У класса DataView есть метод AddNew(), возвращающий новый объект DataRowView. В действительности же новая строка добавляется в базовый объект DataTable только при вызове метода EndEdit() объекта DataRowView. Ниже показано, как средствами объекта DataRowView создать, изменить и удалить строку данных:
// Создание новой строки с использованием DataView
DataRowView drv = dv.AddNew();
drv[0] = 10;
drv[1] = "Hipnotize";
drv.EndEdit();
// Получение и редактирование строки
drv = dv[1];
drv.BeginEdit();
drv[1] = "H";
drv.EndEdit();
// Получение и удаление строки
drv = dv[0];
drv.Delete();
В ADO.NET 2.0 в класс DataView был добавлен метод ТoTable(). Он возвращает объект DataTable, который содержит строки, видимые через свойство RowFilter объекта DataView, и предлагает ряд перегрузок. С помощью различных перегрузок можно управлять свойством TableName нового объекта DataTable, столбцами, которые появятся в объекте DataTable, и даже тем, будет ли этот объект содержать только уникальные записи, основанные на упомянутых столбцах.