- •Упражнение 1. Просмотр таблицы с помощью объектов DbCommand и DbDataReader
- •Упражнение 2. Выборочный просмотр таблицы с помощью объектов DbCommand и DbDataReader
- •Упражнение 3. Выборка данных с помощью объекта DataTable
- •Упражнение 4. Поиск строки DataTable с помощью метода Find()
- •Упражнение 5. Выборка строк DataTable с помощью метода Select()
- •Упражнение 6. Вычисляемые столбцы объектов DataTable
- •Упражнение 7. Работа с объектом DataView
Упражнение 5. Выборка строк DataTable с помощью метода Select()
Выборку строк по определенному критерию традиционно можно выполнить с помощью SQL-запроса. Например, можно запросить всех заказчиков из таблицы Customers, имена которых начинаются на " My ". с помощью такой команды
SELECT * FROM Customers WHERE FirstName LIKE 'My%
Или запросить всех заказчиков, имена которых заканчиваются на " jon "
SELECT * FROM Customers WHERE FirstName LIKE '%jon'
Если нужно выполнять много подобных запросов к одной и той же таблице с помощью SQL, то для этого потребуется часто соединяться сБД, которая может быть занята запросами других пользователей. Хорошо бы было загрузить в кэш полную таблицу и обращаться к ней с запросами сколько угодно раз, не обращаясь к самой центральной БД. Для таких целей предусмотрен метод Select() объектаDataTable, который возвращает коллекцию строк, удовлетворяющих условию выборки. В методе можно также задавать и условие сортировки результирующего набора данных.
В данном упражнении поставим следующую задачу. В раскрывающийся список считаем из БД всех служащих из таблицы Employees. Загрузим в кэш полную таблицу заказов Orders и дадим возможность пользователю просматривать из этой таблицы те заказы, которые оформил конкретный служащий, выбранный в раскрывающемся списке.
Добавьте к решению новый проект оконного приложения с именем WinForms5 и назначьте его стартовым
В панели Solution Explorer в корневой узел проекта WinForms5 перетащите мышью из соседнего проекта папку Data с файломNorthwind.mdb (при этом отклоните предложение мастера конфигурации источника данных)
Добавьте в начало файла Form1.cs подключения пространства имен сборки System.Data.dll, нужные для обеспечения видимости библиотечных классов
// Дополнительные пространства имен
using System.Data.OleDb;
using System.Data.Common;
using System.Collections;
Оформите пользовательский интерфейс формы в соответствии с таблицей
Объект |
Свойство |
Значение |
Пояснения |
Form1 |
Text |
Упражнение 5 |
Заголовок окна |
|
MaximizeBox |
False |
Отключили системную кнопку |
|
FormBorderStyle |
FixedSingle |
Размеры окна менять нельзя |
Label |
Text |
Employee: |
|
ComboBox |
(Name) |
cbEmployees |
|
|
DropDownStyle |
DropDownList |
Текст в поле списка редактировать нельзя |
ListBox |
(Name) |
lstOrders |
|
|
Dock |
Bottom |
|
Форма на этапе проектирования должна выглядеть так
Создайте для события SelectedIndexChanged объекта cbEmployees обработчик и его же присоедините к событиюBindingContextChanged для начального заполнения списка lstOrders
Добавьте в класс Form1 метод LoadTables(), который загружает таблицы Employees и Orders из БД с помощью динамически созданного поставщика данных и SQL-запроса, а также связывает раскрывающийся список с таблицей Employees
Полный код файла Form1 для проекта WinForms5 будет примерно таким
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
// Дополнительные пространства имен
using System.Data.OleDb;
using System.Data.Common;
using System.Collections;
namespace WinForms5
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
LoadTables();
}
//***********************************************************
// Строка соединения с абсолютным путем к БД, определяемым сборкой
// Не используем !!!!!! Заменили объектом-построителем
String ConnectionString(String fileName)
{
string JetEngineString = @"Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Jet OLEDB:Engine Type=5;Data Source=";
string pathToFile = Application.StartupPath.ToString() + "\\Data\\";
return JetEngineString + pathToFile + fileName.Trim() + ".mdb";
}
//**********************************************************
// Поле-ссылка на таблицу Orders
DataTable tableOrders;
void LoadTables()
{
// Используем построитель строки подключения
// для облегчения формирования оной!
OleDbConnectionStringBuilder objConnectionStringBuilder =
new OleDbConnectionStringBuilder();
objConnectionStringBuilder.Provider = "Microsoft.Jet.OLEDB.4.0";
objConnectionStringBuilder.DataSource =
Application.StartupPath.ToString() + @"\Data\Northwind.mdb";
objConnectionStringBuilder.PersistSecurityInfo = true;// Шифровать строку
// Строка соединения с источником данных
String strConnection = objConnectionStringBuilder.ToString();
// Строка запроса
String strSQL = "SELECT EmployeeID, LTRIM(RTRIM(LastName)) + ', '"
+ "+ LTRIM(RTRIM(FirstName)) AS FullName FROM Employees";
// Создаем поставщик данных для таблицы Employees
OleDbDataAdapter adapter = new OleDbDataAdapter(strSQL, strConnection);
// Создаем и заполняем виртуальную таблицу
DataTable tableEmployees = new DataTable();
adapter.Fill(tableEmployees);
tableEmployees.TableName = "Employees";
// Сортируем в прямом порядке: "FullName" или "FullName ASC"
// Сортировка в обратном порядке: "FullName DESC";
tableEmployees.DefaultView.Sort = "FullName ASC";
// Связываем ComboBox с виртуальной таблицей
//cbEmployees.DataSource = tableEmployees; //Связать таблицу несортированной
// Связать через DataView сортированной
cbEmployees.DataSource = tableEmployees.DefaultView;
cbEmployees.DisplayMember = "FullName";
cbEmployees.ValueMember = "EmployeeID";
cbEmployees.SelectedIndex = 0;
// Заполняем виртуальную таблицу Orders всеми записями
OleDbCommand selectCommand = new OleDbCommand(
"SELECT OrderID, EmployeeID, ShipAddress FROM Orders");
selectCommand.Connection = new OleDbConnection(strConnection);
adapter = new OleDbDataAdapter(selectCommand);
tableOrders = new DataTable();
adapter.Fill(tableOrders);
}
private void cbEmployees_SelectedIndexChanged(object sender, EventArgs e)
{
if (tableOrders == null)
return;
// Выбираем строки по условию
String filterExpression = "EmployeeID = " + cbEmployees.SelectedValue;
DataRow[] rows = tableOrders.Select(
filterExpression, // Выражение для фильтра
"ShipAddress ASC"); // Поле сортировки по возрастанию
// "ShipAddress DESC" - сортировка по убыванию!!!
// Очищаем список
lstOrders.Items.Clear();
// Заполняем список
foreach (DataRow row in rows)
{
lstOrders.Items.Add(
"(" + row["EmployeeID"] + ") "
+ row["OrderID"].ToString()
+ "\t" + row["ShipAddress"]);
}
}
}
}
Запустите проект - по выбранному в объекте cbEmployees сотруднику производится выборка закрепленных за ним заказов из таблицы Orders и заполнение списка новой информацией. Соединение с БД выполняется только один раз при формировании таблиц в кэше
Мы старались разнообразить код. Например, для формирования строки подключения мы воспользовались вспомогательным классомOleDbConnectionStringBuilder, а при создании адаптера применяли разные перегрузки его конструктора. Метод Select() объектаDataTable производит выборку строк по выражению, которое равноценно условию, применяемому в SQL-запросе после ключевого слова WHERE. Меняя это выражение можно получать различные представления объектной модели таблицы данных.
