ADO.NET. Управление базами данных. Связь по схеме OLE DB провайдера. Коррекция стилей DataGridView, страница 29

Как видите, сначала определяется схема таблицы DataTable dt путем отбора 4-х полей реальной таблицы Customers (на самом деле она содержит 11 колонок). Затем DataTable заполняется путем чтения всех записей таблицы БД. Далее осуществляется привязка выпадающего списка к данным таблицы в памяти.

Напомним, что механизм Complex DataBinding требует определить для привязываемого элемента два свойства: DataSource и DisplayMember. Для некоторых элементов (в их число входит выпадающий список) имеет смысл определить еще одно свойство — ValueMember.

DataSource задает источник данных, DisplayMember задает отображаемое в списке поле таблицы (мы выбрали колонку City), ValueMember определяет SelectedValue — результат, возвращаемый списком при выборе строки. Таким образом, мы настроили механизм привязки к данным так, чтобы он наполнил список данными, взятыми из колонки City таблицы Customers. При выборе строки списка SelectedValue будет содержать город. В нашем случае это удобно, но в некоторых случаях в качестве SelectedValue следует задавать CustomerID, а не город.

В начальный момент DataGridView отображает все (неотфильтрованные) данные реальной таблицы, так как он привязан к данным DataTable, а не DataView (grid.DataSource = dt;). При перемещении фокуса вдоль строк элемента grid текст comboCity синхронизирован, и наоборот, при выборе строки списка comboCity изменяется текущая строка элемента grid, так как оба они привязаны к одному источнику данных (DataTable).

В обработчик события SelectedIndexChanged добавим код, который использует имя города для задания фильтра отбора данных DataView. Связывая DataGridView с DataView, получаем задуманный эффект.

void comboCity_SelectedIndexChanged (object sender, EventArgs e)

{

   dv.RowFilter = "City = '" + comboCity.SelectedValue + "'";

   bs = new BindingSource (dv, "");

   bn.BindingSource = bs;

   grid.DataSource = bs;   // Grid меняет источник своих данных

}

Другие критерии отбора данных (например, отбор по состоянию строк — DataViewRowState) мы рассматривали ранее. Напомним, что отбор строк можно производить и без помощи класса DataView. Следующий фрагмент использует метод Select класса DataTable.

DataRow[] rows = dt.Select("City='London'", "Company DESC", DataViewRowState.CurrentRows);

foreach (DataRow row in rows)

  Console.WriteLine("Company name: " + row["Company", DataRowVersion.Current]);

Вставьте его в конец MainForm_Load и запустите в режиме отладки. В окне Output вы должны увидеть список компаний, расположенных в городе London, упорядоченных по убыванию их имен.

Метод ExecuteScalar

Результатом выполнения операций над таблицами реляционной базы данных обычно являются другие таблицы? состоящие из множества строк (result set), удовлетворяющих критерию отбора. Но иногда нужно получить от базы не множество строк, а некоторую скалярную величину. Обычно это результат выполнения SQL-команд вида: COUNT, MAX, MIN, AVERAGE. Для этой цели используется метод ExecuteScalar, имеющийся во всех классах DbCommand. Метод позволяет эффективно выполнить SQL-запрос, или хранимую процедуру и получить скалярную величину.

·  Для иллюстрации этого метода добавьте на форму элемент вида FlowLayoutPanel по имени custPanel.

·  Внутрь панели добавьте две метки: lblText с текстом # Customers: и lblCount без текста.

·  Введите в класс формы новый метод SetCount, в котором мы воспользуемся методом ExecuteScalar для вычисления количества заказчиков, живущих в выбранном городе. В начальный момент панель надо сделать невидимой.

·  Вызов SetCount вставьте в обработчик события SelectedIndexChanged.

  void SetCount()

  {

   cn.Open();

   OleDbCommand cmd = new OleDbCommand("SELECT COUNT(*) from Customers where City = ?", cn);

   cmd.Parameters.Add("City", OleDbType.VarChar, 15, "City").Value = comboCity.SelectedValue;

   lblCount.Text = cmd.ExecuteScalar().ToString();

   custPanel.Show();

   cmd.Dispose();

   cn.Close();

  }