Опубликован: 05.08.2010 | Доступ: свободный | Студентов: 2005 / 43 | Оценка: 4.50 / 4.40 | Длительность: 60:26:00
Самостоятельная работа 5:

Просмотр данных 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();  // Закрываем соединение
        }
    }
}
  • Запустите проект - все работает как задумали


Алексей Бабушкин
Алексей Бабушкин

При выполнении в лабораторной работе упражнения №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" или один из зависимых от них компонентов. Не удается найти указанный файл.

Делаю все пунктуально. В чем может быть проблема?