При выполнении в лабораторной работе упражнения №1 , а именно при выполнении нижеследующего кода: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Microsoft.Xna.Framework.Graphics;
namespace Application1 { public partial class MainForm : Form { // Объявим поле графического устройства для видимости в методах GraphicsDevice device;
public MainForm() { InitializeComponent();
// Подпишемся на событие Load формы this.Load += new EventHandler(MainForm_Load);
// Попишемся на событие FormClosed формы this.FormClosed += new FormClosedEventHandler(MainForm_FormClosed); }
void MainForm_FormClosed(object sender, FormClosedEventArgs e) { // Удаляем (освобождаем) устройство device.Dispose(); // На всякий случай присваиваем ссылке на устройство значение null device = null; }
void MainForm_Load(object sender, EventArgs e) { // Создаем объект представления для настройки графического устройства PresentationParameters presentParams = new PresentationParameters(); // Настраиваем объект представления через его свойства presentParams.IsFullScreen = false; // Включаем оконный режим presentParams.BackBufferCount = 1; // Включаем задний буфер // для двойной буферизации // Переключение переднего и заднего буферов // должно осуществляться с максимальной эффективностью presentParams.SwapEffect = SwapEffect.Discard; // Устанавливаем размеры заднего буфера по клиентской области окна формы presentParams.BackBufferWidth = this.ClientSize.Width; presentParams.BackBufferHeight = this.ClientSize.Height;
// Создадим графическое устройство с заданными настройками device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, this.Handle, presentParams); }
protected override void OnPaint(PaintEventArgs e) { device.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue);
base.OnPaint(e); } } } Выбрасывается исключение: Невозможно загрузить файл или сборку "Microsoft.Xna.Framework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d" или один из зависимых от них компонентов. Не удается найти указанный файл. Делаю все пунктуально. В чем может быть проблема? |
Просмотр данных OLE DB средствами ADO.NET
Упражнение 2. Выборочный просмотр таблицы с помощью объектов DbCommand и DbDataReader
Часто пользователь хочет просмотреть часть результатов, хранящихся в некоторой таблице БД. Здесь также может пригодиться модуль чтения DbDataReader. В данном упражнении мы разработаем форму, в которой пользователь выбирает из раскрывающегося списка конкретного служащего и просматривает заказы, обслуживаемые этим сотрудником. Здесь мы вновь будем использовать файловую БД Northwind.mdb, схема связей которой изображена на рисунке, построенном в MS Office Access:
- Добавьте к решению ADO командой File/Add/New Project новый проект с именем WinForms2 и назначьте его стартовым командой Project/Set as StartUp Project
- В панели Solution Explorer создайте папку Data для корневого узла проекта командой Add/New Folder и скопируйте в нее перетаскиванием мышью через панель Solution Explorer из предыдущего проекта файл Northwind.mdb. При появлении мастера Data Source Configuration Wizard отмените его кнопкой Cancel
- Поместите на форму из панели Toolbox нужные компоненты и настройте их в соответствии с таблицей свойств
Компонент | Свойство | Значение |
---|---|---|
Form | Text | Упражнение 2 |
MaximizeBox | False | |
Label | Text | Сотрудник: |
ComboBox | (Name) | cbEmployees |
ListBox | (Name) | lstCustomers |
Dock | Bottom |
Вначале мы заполним раскрывающийся список ComboBox сотрудниками, обслуживающими заказы. Список будем заполнять в конструкторе формы.
- Модифицируйте файл Form1.cs следующим образом
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 WinForms2 { public partial class Form1 : Form { // Создаем объект списка сотрудников ArrayList dbEmployeesList = new ArrayList();// Поле public Form1() { InitializeComponent(); LoadEmployees(); } // Строка соединения с абсолютным путем к БД, определяемым сборкой 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"; } // Заполнение раскрывающегося списка из БД void LoadEmployees() { // Создаем объект соединения OleDbConnection objConnection = new OleDbConnection(ConnectionString("Northwind")); // Создаем объект команды OleDbCommand objCommand = new OleDbCommand( "SELECT EmployeeID, RTRIM(LastName) + ', ' + RTRIM(FirstName) AS FullName FROM Employees", objConnection); // Открываем соединение objConnection.Open(); // Читаем в DbDataReader OleDbDataReader reader = objCommand.ExecuteReader(); // Заполняем автономный список записей foreach (DbDataRecord rec in reader) { dbEmployeesList.Add(rec); } // Закрываем соединение objConnection.Close(); // Связываем автономный список записей с ComboBox cbEmployees.BeginUpdate(); cbEmployees.DataSource = dbEmployeesList; cbEmployees.DisplayMember = "FullName"; cbEmployees.ValueMember = "EmployeeID"; cbEmployees.EndUpdate(); cbEmployees.SelectedIndex = 0;// Устанавливаем на первый элемент } } }
- Запустите проект WinForms2 и убедитесь, что раскрывающийся список заполняется информацией из таблицы Employees БД Northwind
Теперь, по выбранному сотруднику, мы сформируем список заказов из таблицы Orders, которые этот сотрудник обслуживает. Причем, в этом списке нам нужен будет только идентификатор заказчиков, сделавших заказ. В дальнейшем, загружая информацию из таблицы заказчиков ( Customers ), мы выбирем только тех из них, которые делали заказы у заданного сотрудника. Останется только отобразить этих заказчиков пользователю.
- Создайте обработчик события SelectedIndexChanged для объекта cbEmployees и дополните класс Form1 проекта WinForms2 следующим кодом
private void cbEmployees_SelectedIndexChanged(object sender, EventArgs e) { LoadOrders(); // Выбираем информацию из таблицы Orders // Прореживаем список ArrayList tmpList = new ArrayList(); for (int i = 0; i < ordersCustomerID.Count; i++) { object val = ordersCustomerID[i]; if (tmpList.IndexOf(val) == -1) tmpList.Add(val); } //ordersCustomerID = tmpList.Clone() as ArrayList; ordersCustomerID = tmpList; // Бросаем старый список ordersCustomerID.Sort(); // Сортируем список lstCustomers.Items.Clear(); // Чистим ListBox // Отображаем список for (int i = 0; i < ordersCustomerID.Count; i++) lstCustomers.Items.Add(ordersCustomerID[i]); } // Получение всех закрепленных за сотрудником заказов ArrayList ordersCustomerID = new ArrayList(); void LoadOrders() { if (cbEmployees.SelectedIndex == -1) return; // Создаем объект соединения OleDbConnection objConnection = new OleDbConnection(ConnectionString("Northwind")); // Создаем объект команды OleDbCommand objCommand = new OleDbCommand( "SELECT CustomerID FROM Orders WHERE (EmployeeID = ?)", objConnection); objCommand.Parameters.Add(new OleDbParameter()); objCommand.Parameters[0].Value = cbEmployees.SelectedValue.ToString(); objConnection.Open(); // Открываем соединение OleDbDataReader reader = objCommand.ExecuteReader();// Читаем в DbDataReader if (reader.HasRows) { // Чистим список ordersCustomerID.Clear(); while(reader.Read()) { ordersCustomerID.Add(reader["CustomerID"]); } } objConnection.Close(); // Закрываем соединение }
- Запустите проект - список lstCustomers заполняется неповторяющимися идентификаторами заказчиков из поля CustomerID
Обратите внимание, что список lstCustomers заполняется только после явного выбора служащего в объекте cbEmployees при возбуждении события cbEmployees.SelectedIndexChanged, но при первом запуске формы остается пустым. Можно это так и оставить, но лучше - пусть заполняется и в самом начале.
- Выделите на форме объект cbEmployees, в панели Properties установите режим Events, найдите событие BindingContextChanged и подпишите его на уже существующий обработчик cbEmployees_SelectedIndexChanged()
- Запустите проект - теперь список заполняется и в самом начале появления формы на экране
Задача, которую мы поставили в данном упражнении, решена еще не полностью. Цель заключалась в просмотре заказчиков по выбранному служащему, а пока отображаются только идентификаторы заказчиков. Теперь нужно из таблицы Customers для каждого CustomerID, закрепленного за выбранным служащим, запросить значение поля CompanyName и отобразить в списке lstCustomers.
- Модифицируйте класс Form1 проекта WinForms2 следующим образом
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 WinForms2 { public partial class Form1 : Form { // Создаем объект списка сотрудников ArrayList dbEmployeesList = new ArrayList();// Поле public Form1() { InitializeComponent(); LoadEmployees(); LoadCustomers(); } // Строка соединения с абсолютным путем к БД, определяемым сборкой 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"; } // Заполнение раскрывающегося списка из БД void LoadEmployees() { // Создаем объект соединения OleDbConnection objConnection = new OleDbConnection(ConnectionString("Northwind")); // Создаем объект команды OleDbCommand objCommand = new OleDbCommand( "SELECT EmployeeID, RTRIM(LastName) + ', ' + RTRIM(FirstName) AS FullName FROM Employees", objConnection); // Открываем соединение objConnection.Open(); // Читаем в DbDataReader OleDbDataReader reader = objCommand.ExecuteReader(); // Заполняем автономный список записей foreach (DbDataRecord rec in reader) { dbEmployeesList.Add(rec); } // Закрываем соединение objConnection.Close(); // Связываем автономный список записей с ComboBox cbEmployees.BeginUpdate(); cbEmployees.DataSource = dbEmployeesList; cbEmployees.DisplayMember = "FullName"; cbEmployees.ValueMember = "EmployeeID"; cbEmployees.EndUpdate(); cbEmployees.SelectedIndex = 0;// Устанавливаем на первый элемент } private void cbEmployees_SelectedIndexChanged(object sender, EventArgs e) { LoadOrders(); // Выбираем информацию из таблицы Orders // Прореживаем список ArrayList tmpList = new ArrayList(); for (int i = 0; i < ordersCustomerID.Count; i++) { object val = ordersCustomerID[i]; if (tmpList.IndexOf(val) == -1) tmpList.Add(val); } //ordersCustomerID = tmpList.Clone() as ArrayList; ordersCustomerID = tmpList; // Бросаем старый список ordersCustomerID.Sort(); // Сортируем список lstCustomers.Items.Clear(); // Чистим ListBox // Отображаем список for (int i = 0; i < ordersCustomerID.Count; i++) { //lstCustomers.Items.Add(ordersCustomerID[i]); int index = customerID.IndexOf(ordersCustomerID[i]); lstCustomers.Items.Add(customerID[index] + "\t - " + companyName[index]); } } // Читаем таблицу заказчиков Customers ArrayList companyName = new ArrayList(); ArrayList customerID = new ArrayList(); void LoadCustomers() { OleDbConnection objConnection = new OleDbConnection(ConnectionString("Northwind")); OleDbCommand objCommand = new OleDbCommand( "SELECT CustomerID, CompanyName FROM Customers", objConnection); objConnection.Open(); OleDbDataReader reader = objCommand.ExecuteReader(CommandBehavior.CloseConnection); while (reader.Read()) { customerID.Add(reader.GetString(0)); companyName.Add(reader.GetString(1)); } reader.Close(); } // Получение всех закрепленных за сотрудником заказов ArrayList ordersCustomerID = new ArrayList(); void LoadOrders() { if (cbEmployees.SelectedIndex == -1) return; // Создаем объект соединения OleDbConnection objConnection = new OleDbConnection(ConnectionString("Northwind")); // Создаем объект команды OleDbCommand objCommand = new OleDbCommand( "SELECT CustomerID FROM Orders WHERE (EmployeeID = ?)", objConnection); objCommand.Parameters.Add(new OleDbParameter()); objCommand.Parameters[0].Value = cbEmployees.SelectedValue.ToString(); objConnection.Open(); // Открываем соединение OleDbDataReader reader = objCommand.ExecuteReader();// Читаем в DbDataReader if (reader.HasRows) { // Чистим список ordersCustomerID.Clear(); while(reader.Read()) { ordersCustomerID.Add(reader["CustomerID"]); } } objConnection.Close(); // Закрываем соединение } } }
- Запустите проект - все работает как задумали