Технология Microsoft ADO.NET

       

Поиск данных


Технология ADO .NET предоставляет значительные возможности для поиска данных - такие объекты, как DataSet, DataTable, содержат специализированные методы для быстрого решения этой задачи. Между тем свойство RowFilter объекта DataView может применяться для создания простого и эффективного поиска. Запускаем Visual Studio .NET и создаем новый проект. В окне New Project выбираем тип Windows Control Library, называем его "FindControl" (рис. 9.16):


Рис. 9.16.  Выбор шаблона Windows Control Library

Появляется форма пользовательского (композитного) элемента управления. Устанавливаем следующие свойства:

UserControl1, свойство Значение
Name FindCheckBox
Size 230; 70

В окне Solution Explorer изменяем название "UserControl1.cs" на "FindCheckBox.cs". Перетаскиваем на форму из окна Toolbox текстовое поле, надпись и элемент CheckBox. Настраиваем их свойства:

CheckBox1, свойство ЗначениеtextBox1, свойство Значение
Name chbForSearching
Location 8; 32
Text
Name txtColumnValue
Location 32; 32
Size 184; 20
Text
label1, свойство Значение
Name lblColumnName
Location 40; 8
Text ColumnName

Переходим к коду. В конструкторе формы отключаем доступность текстового поля и привязываем обработчик события CheckedChanged для элемента CheckBox:

public FindCheckBox() { InitializeComponent(); txtColumnValue.Enabled = false; chbForSearching.CheckedChanged += new EventHandler(chbForSearching_CheckedChanged); }

В классе формы создаем обработчик события CheckedChanged для CheckBox и определяем действия для значений текстового поля, надписи и элемента CheckBox:

private void chbForSearching_CheckedChanged(object sender, EventArgs e) { txtColumnValue.Enabled = chbForSearching.Checked; } [Category("Appearance"), Description("Название поля, по которому будет осуществляться поиск")] public string ColumnName { get {return lblColumnName.Text;} set {lblColumnName.Text = value;} } [Category("Appearance"), Description("Ключевое слово для поиска")] public string ColumnValue { get {return txtColumnValue.Text;} set {txtColumnValue.Text = value;} }


[Category("Appearance"), Description("Включение поиска по заданному полю")] public bool SearchEnabled { get {return chbForSearching.Checked;} set {chbForSearching.Checked = value;} }

Свойства ColumnName, ColumnValue и SearchEnabled будут свойствами композитного элемента управления, которые будут отображаться в его окне Properties. В квадратных скобках указан атрибут для помещения свойства в заданную группу и описание, выводимое на информационную панель. Компилируем приложение (Ctrl+Shift+B) и закрываем его. Создаем новое Windows-приложение, называем его "FindCustomers". Перетаскиваем на форму следующие элементы управления: Panel (свойству Dock устанавливаем значение Left), Splitter и DataGrid (свойству Dock устанавливаем значение Fill). В окне Toolbox щелкаем правой кнопкой мыши на вкладке Windows Forms и в появившемся контекстном меню выбираем пункт "Add \ Remove Items_". В появившемся окне Customize Toolbox на вкладке .NET Framework Components нажимаем кнопку "Browse" (рис. 9.17, А) и переходим в директор ию, где расположена сборка композитного элемента FindControl (у меня это D:\Uchebnik\Code\Glava4\FindControl\bin\Debug, сборка FindControl.dll) (рис. 9.17, Б). После выбора сборки она появляется в окне Customize Toolbox (рис. 9.17, В).


увеличить изображение
Рис. 9.17.  Добавление композитного элемента. А - окно "Customize Toolbox", Б - Выбор сборки FindControl.dll, В - добавленная сборка на вкладке ".NET Framework Components"

Нажимаем кнопку "OK" и перетаскиваем на панель формы из окна Toolbox четыре копии элемента FindCheckBox. Добавляем также кнопку поиска (рис. 9.18). Устанавливаем следующие свойства элементов:

findCheckBox1, свойство Значение
ColumnName CustomerID
Name fcbCustomerID
findCheckBox2, свойство Значение
ColumnNameCompanyName
Name fcbCompanyName
findCheckBox3, свойство Значение
ColumnName ContactName
Name FcbContactName
findCheckBox4, свойство Значение
ColumnName Phone
Name fcbPhone
button1, свойство Значение
Name btnSearch
Text Поиск



увеличить изображение
Рис. 9.18.  Расположение элементов на форме. Окно Properties композитного элемента

Обратите внимание (рис. 9.18), что в окне Properties, при групповом расположении, свойство ColumnName находится в группе Appearance. На информационную панель выводится описание этого свойства на русском языке. Именно эти параметры мы и указывали при создании композитного элемента.

Для того чтобы упростить код, создадим подключение к базе данных при помощи визуальных средств студии. В окне Toolbox переходим на вкладку Data, перетаскиваем на форму SqlDataAdapter и настраиваем извлечение таблицы Customers базы данных NorthwindCS. Выделяем затем sqlDataAdapter1 на панели компонент, в окне Properties переходим по ссылке "Generate DataSet". Вводим имя "dsCustomers". В конструкторе формы добавляем код для заполнения элемента DataGrid данными при загрузке:

public Form1() { InitializeComponent(); sqlDataAdapter1.Fill(dsCustomers1); dataGrid1.DataSource = dsCustomers1.Tables["Customers"].DefaultView; }

В классе формы создаем метод FindCustomers, в котором будет осуществляться обработка1):

private void FindCustomers() { //Создаем экземпляр filteringFields класса ArrayList ArrayList filteringFields = new ArrayList(); //Если элемент fcbCustomerID доступен для поиска if (fcbCustomerID.SearchEnabled) //Добавляем в массив filteringFields значение текстового поля ColumnValue filteringFields.Add("CustomerID LIKE \'" + fcbCustomerID.ColumnValue + "%\'");

if (fcbCompanyName.SearchEnabled) filteringFields.Add("CompanyName LIKE \'" + fcbCompanyName.ColumnValue + "%\'");

if (fcbContactName.SearchEnabled) filteringFields.Add("ContactName LIKE \'" + fcbContactName.ColumnValue + "%\'");

if (fcbPhone.SearchEnabled) filteringFields.Add("Phone LIKE \'" + fcbPhone.ColumnValue + "%\'");

string filter = ""; //Комбинируем введенные в текстовые поля значения. //Для объединения используем логический оператор "ИЛИ" if (filteringFields.Count == 1) filter = filteringFields[0].ToString(); else if (filteringFields.Count > 1) { for(int i = 0; i < filteringFields.Count - 1; i++) filter += filteringFields[i].ToString() + " OR "; //Для объединения полей в запросе используем логический оператор "И" //for(int i = 0; i < filteringFields.Count - 1; i++) //filter += filteringFields[i].ToString() + " AND ";



filter += filteringFields[filteringFields.Count - 1].ToString(); } // Создаем экземпляр dvSearch класса DataView DataView dvSearch = new DataView(dsCustomers1.Customers); //Передаем свойству RowFilter объекта DataView скомбинированное значение filter dvSearch.RowFilter = filter; dataGrid1.DataSource = dvSearch; }

Добавляем обработчик кнопки "Поиск":

private void btnSearch_Click(object sender, System.EventArgs e) { try { FindCustomers(); } catch(Exception ex) { MessageBox.Show(ex.Message); } }

Запускаем приложение. При определении логического оператора "ИЛИ" в методе FindCustomers поисковый запрос выводит записи, содержащие хотя бы одно значение из введенных полей (рис. 9.19, А), при определении оператора "И" - запись, содержащую все эти значения (рис. 9.19, Б).


увеличить изображение
Рис. 9.19.  Готовое приложение "FindCustomers". А - Запрос с оператором "ИЛИ" возвращает две записи, содержащие в разных полях введенное значение. Б - Запрос с оператором "И" не возвращает ничего, поскольку в таблице нет ни одной записи, содержащей оба значения

В программном обеспечении к курсу вы найдете приложения FindControl и FindCustomers (Code\Glava4\ FindControl и FindCustomers).


Содержание раздела