Модификация приложения Windows Forms : OLE



 

Для соединения с базой данных Microsoft Office Access 2003 и ниже (файл *. mdb) в C# следует использовать класс OleDbConnection со следующими параметрами соединения:

Provider=Microsoft.Jet.OLEDB.4.0; Data Source=DataBaseFile

Здесь DataBaseFile — абсолютный путь к файлу базы данных Access. «Провайдер» соединения должен иметь значение Microsoft . Jet . OLEDB .4.0.

Для соединения с базой данных Microsoft Office Access 2007 и выше (файл *.accdb) в C# следует использовать класс OleDbConnection со следующими параметрами соединения:

Provider=Microsoft.ACE.OLEDB.12.0; Data Source=DataBaseFile

Здесь DataBaseFile — абсолютный путь к файлу базы данных Access. «Провайдер» соединения должен иметь значение Microsoft . ACE . OLEDB .12.0 либо для версии Access 2010: Microsoft . ACE . OLEDB .14.0.

 

Пример:

 

   String ConnetionString = null;

   ConnetionStringO = "Provider=Microsoft.ACE.OLEDB.12.0;" +

   @"Data Source=D:\Database.accdb";

   ConnectionOLE1 = new OleDbConnection(ConnetionStringOLE1);

 

Для отправки SQL-запросов и чтения их результатов используются объекты OleDbCommand и OleDbDataReader.

 

Для выполнения запросов на вставку, изменение, или удаление данных из базы данных следует использовать метод класса OleDbCommand: ExecuteNonQuery(). Его вызов выполняет указанный в свойстве CommandText класса OleDbCommand запроc и возвращает int-число затронутых запросом полей.

 

Пример:

 

  OleDbConnection Conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=Database.mdb"); // Инициализируем параметры соединения

  Conn.Open(); // Открываем соединение с базой даннфх

  OleDbCommand Cmd = new OleDbCommand(); // Создаём команду

  Cmd.CommandText = "INSERT INTO Main_Table VALUES (1,2,3)"; // Текст команды

  int rowsAffected = Cmd.ExecuteNonQuery(); // Выполнение команды с возвратом в int

  System.Windows.Forms.MessageBox.Show(rowsAffected.ToString()); // Вывод результата

 

Если база данных из примеры выше пустая, то int будет равно единице.

 

Во время выполнения команд вставки (SQL: INSERT INTO) можно использовать параметры, что может пригодиться, например, для добавления в базу данных файла изображения.

 

Пример:

 

   OleDbCommand Сmd = new OleDbCommand("INSERT INTO Main_Table (columns) VALUES (@param)", Сonn);

   Сmd.Parameters.Add("@param", "abc[[''[]''kl'm");

   Сmd.ExecuteNonQuery();

 

При каких-либо ошибках в синтаксисе, или структуре SQL-запроса, программа падает в OS Loader Lock (фактически прерывается работа), и не дает никакой информации о произошедшей ошибке. Чтобы этого избежать и получить довольно исчерпывающую информацию о произошедшей ошибке, следует выполнять запросы в try-catch блоках. В коде работы подобные приёмы будут использованы повсеместно.

 

Теперь приступим к формированию второй группы элементов и её функциональности. Для начала расставим элементы как показано на рисунке ниже:

 

Рис. 4. 1. Расстановка элементов первой группы (OLE # 1)

 

Здесь представлены три кнопки Button, один ListBox (по центру), простой погашенный TextBox, как в предыдущей группе, и четыре TextBox’а для ввода с клавиатуры данных, которые будут добавлять в базу данных. Слева от каждого размещены по одному текстовому элементу: Label. Также с панели инструментов было добавлен ещё один OpenFileDialog-элемент.

 

Функциональность блока будет следующей. При нажатии на кнопку Выбрать базу данных, будет предложено выбрать одну из двух возможных типов базы: это база данных для старых версий Access (*. mdb) и для новых (*. accdb). После этого будет выдано сообщение об успехе или неудаче выбора с описанием причины ошибки в случае неудачи. Далее при нажатии Прочитать все записи, в центральный ListBox будут занесены все записи из базы данных. Ввод значений в TextBox’ы слева и нажатие кнопки Добавить записи сохранит в нашей базе новый записи. Будет использована та же самая база данных, что и для предыдущего блока: LWP 10- DB - ODBC . mdb, а также копия этой же базы, сохранённая как файл *. accdb, для версии Access 2007 или Access 2010. База: LWP 10- DB - OLE . accdb.

 

По порядку распишем Свойства каждого элемента:

 

Button:

(Name): B_OLE_1_Search
Text: Выбрать базу данных
Size: 200; 23

Button:

(Name): B_OLE_1_Read
Text: Прочитать все записи
Size: 200; 23

Button:

(Name): B_OLE_1_Add
Text: Добавить записи
Size: 200; 23

TextBox:

(Name): TB_OLE_1_Path
ReadOnly: True

ListBox:

(Name): LB_OLE_1

GroupBox:

(Name): GB_OLE_1
Text: OLE # 1

OpenFileDialog:

(Name): OFD_OLE_1
InitialDirectory: D:\
Filter База данных *.mdb|*.mdb|База данных *.accdb|*.accdb

TextBox:

(Name): TB_OLE_1_1

TextBox:

(Name): TB_OLE_1_2

TextBox:

(Name): TB_OLE_1_3

TextBox:

(Name): TB_OLE_1_4

 

Откроем файл LWP 10 Main . cs и в самом начале добавим две ссылки:

 

using System.Data.OleDb; // OLE

using System.IO; // Для получения расширения файла базы данных

 

Найдём:

 

public partial class LWP10Main : Form

{

   Double Counter = 4;

   OdbcConnection ConnectionOBDC;

 

Добавим после:

 

   String ConnetionStringOLE1 = null; // Переменная для сохранения данных соединения

   OleDbConnection ConnectionOLE1; // Объект для открытия подключения к базе данных

    String SQL_OLE = null; // Переменная для поискового запроса

   String SQL_OLE_ADD = null; // Переменная для добавления данных

 

Найдём:

 

   public LWP10Main()

   {

       InitializeComponent();

       TB_ODBC_Path.Text = "D:\\LWP10-DB-ODBC.mdb";

 

Добавим после:

 

       TB_OLE_1_Path.Text = "D:\\LWP10-DB-OLE.accdb";

       B_OLE_1_Read.Enabled = false;

       B_OLE_1_Add.Enabled = false;

       TB_OLE_1_1.Text = Counter.ToString();

       SQL_OLE = "SELECT * FROM [Главная таблица]";

 

Событие Click кнопки Выбрать базу данных:

 

   private void B_OLE_1_Search_Click(object sender, EventArgs e)

   {

 

       if (OFD_OLE_1.ShowDialog() == DialogResult.OK)

       {

           B_OLE_1_Read.Enabled = true; // Активируем кнопку "Прочитать все записи"

           B_OLE_1_Add.Enabled = true;

           //TB_OLE_1_Path.Text = OFD_OLE_1.FileName;

           Directory.CreateDirectory(Path.GetDirectoryName(OFD_OLE_1.FileName) + @"\Копии"); // Создаём директорию под изменённые БД

           File.Copy(OFD_OLE_1.FileName, Path.GetDirectoryName(OFD_OLE_1.FileName) + @"\Копии\" + OFD_OLE_1.SafeFileName, true); // Копируем туда выбранную БД (перезаписываем, в случае обнаружения похожего файла)

           if (Path.GetDirectoryName(OFD_OLE_1.FileName) == Directory.GetDirectoryRoot(OFD_OLE_1.FileName)) // Проверяем путь, если находимся в корневой директории диска, режем один слеш

               TB_OLE_1_Path.Text = Path.GetDirectoryName(OFD_OLE_1.FileName) + @"Копии\" + OFD_OLE_1.SafeFileName;

           else

               TB_OLE_1_Path.Text = Path.GetDirectoryName(OFD_OLE_1.FileName) + @"\Копии\" + OFD_OLE_1.SafeFileName;

 

           if (Path.GetExtension(OFD_OLE_1.FileName) == ".mdb") // Узнаём расширение файла выбранного в диалоге открытия (указываем полный путь) и сравниваем его с ".mdb"

           {

               ConnetionStringOLE1 = "Provider=Microsoft.Jet.OLEDB.4.0;" +

                   @"Data Source=" + TB_OLE_1_Path.Text + "";

               MessageBox.Show("Выбрана база данных " + TB_OLE_1_Path.Text + " формата: *" + Path.GetExtension(TB_OLE_1_Path.Text) + "!", "Работа с базами данных (C#) :: OLE # 1");

           }

 

           if (Path.GetExtension(OFD_OLE_1.FileName) == ".accdb")

           {

               ConnetionStringOLE1 = "Provider=Microsoft.ACE.OLEDB.12.0;" +

                   @"Data Source=" + TB_OLE_1_Path.Text + "";

               MessageBox.Show("Выбрана база данных " + TB_OLE_1_Path.Text + " формата: *" + Path.GetExtension(TB_OLE_1_Path.Text) + "!", "Работа с базами данных (C#) :: OLE # 1");

           }

       }

   }

 

Событие Click кнопки Показать все записи:

 

   private void B_OLE_1_Read_Click(object sender, EventArgs e)

   {

       LB_OLE_1.Items.Clear();

       ConnectionOLE1 = new OleDbConnection(ConnetionStringOLE1);

 

       try

       {

           ConnectionOLE1.Open(); // Открываем соединение

           MessageBox.Show("Соединение с базой данных " + TB_OLE_1_Path.Text + " успешно открыто!", "Работа с базами данных (C#) :: OLE # 1");

       }

       catch (Exception ex) // Ловим исключение и вытаскиваем ошибку через ex.Message

       {

           MessageBox.Show("Невозможно открыть соединение с базой данных " + TB_OLE_1_Path.Text + " (" + ex.Message + ")!", "Работа с базами данных (C#) :: OLE # 1");

       }

       OleDbCommand Command = new OleDbCommand(SQL_OLE, ConnectionOLE1); // Формируем SQL-команду для текущего подключения

       OleDbDataReader DataReader = Command.ExecuteReader(); // Формируем объект для чтения данных из базы данных

       LB_OLE_1.Items.Add(Command.CommandText); // Посылаем текст команды в ListBox

       // Организуем циклический перебор полученных записей

       while (DataReader.Read())

       {

           LB_OLE_1.Items.Add(DataReader["Ключевое поле"].ToString() + " | " + DataReader["Первое поле"].ToString() + " | " + DataReader["Второе поле"].ToString() + " | " + DataReader["Третье поле"].ToString());

       }

       // Закрываем потоки чтения и соединения

       DataReader.Close();

       ConnectionOLE1.Close();

   }

 

Событие Click кнопки Добавить записи:

 

   private void B_OLE_1_Add_Click(object sender, EventArgs e)

   {

       LB_OLE_1.Items.Clear(); // Очищаем ListBox перед использованием

       ConnectionOLE1 = new OleDbConnection(ConnetionStringOLE1); // Передаём параметры объекту соединения

 

       try

       {

           ConnectionOLE1.Open(); // Открываем соединение

           MessageBox.Show("Соединение с базой данных " + TB_OLE_1_Path.Text + " успешно открыто!", "Работа с базами данных (C#) :: OLE # 1");

       }

       catch (Exception ex)

       {

           MessageBox.Show("Невозможно открыть соединение с базой данных " + TB_OLE_1_Path.Text + " (" + ex.Message + ")!", "Работа с базами данных (C#) :: OLE # 1");

       }

       SQL_OLE_ADD = "INSERT INTO [Главная таблица] VALUES('" + Counter.ToString() + "', '" + this.TB_OLE_1_2.Text + "', '" + this.TB_OLE_1_3.Text + "', '" + this.TB_OLE_1_4.Text + "');";

       OleDbCommand Command = new OleDbCommand(SQL_OLE_ADD, ConnectionOLE1);

 

       try

       {

           Command.ExecuteNonQuery(); // Выполняем команду

       }

       catch (Exception ex)

       {

           MessageBox.Show("Невозможно выполнить команду с базой данных " + TB_OLE_1_Path.Text + " (" + ex.Message + ")!", "Работа с базами данных (C#) :: OLE # 1");

       }

       LB_OLE_1.Items.Add(Command.CommandText); // Отправляем текст команды в ListBox

       Counter++;

       TB_OLE_1_1.Text = Counter.ToString();

   }

 

Компилируем приложение (Debug) и запускаем:

 

Рис. 4. 2. Окончательная работа блока: OLE # 1

 

Предположим, что работа в таком виде с базами данных нас не устраивает. Например, весьма неудобно для базы, где в таблице есть более сотни столбцов, делать эту самую сотню TextBox’ов. В этом случае, когда требуется наглядность данных в приложении и малые трудозатраты лучше нужно использовать элемент управления DataGridView и связанные с ним другие элементы, такие как например DataSet.

Оба элемента можно найти на панели элементов на вкладе Данные.

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

Для демонстрации работы с этими элементами организуем третью группу элементов: OLE # 2. Приложение же будет выполнять тот же запрос, что и в предыдущем примере, но будет помещать результат в объект DataSet, который подключается к элементу управления DataGridView, а тот автоматически отображает все данные. Для сохранения данных в базе будет использоваться метод «двухсторонней привязки3 данных», который позволит не только просматривать открывшуюся таблицу, но и вводить изменения в элемент DataGridView, добавляя новые строки, изменяя содержимое имеющихся строк и удаляя ненужные. Объекты класса DataAdapter способны выполнять как операцию SELECT, получая данные запроса из базы данных, так и команды INSERT, UPDATE и DELETE, изменяя содержимое таблицы базы данных.

 

Но прописывать данные команды самостоятельно надобности нет. Пространство имен System.Data содержит небольшой, но очень полезный класс CommandBuilder, который умеет создавать команды SQL и автоматически их выполнять.

 

ПРИМЕЧАНИЕ № 3: Подключение источника данных к визуальному элементу управления называется привязкой, или связыванием данных.

 

Теперь приступим к формированию третьей группы элементов и её функциональности. Для начала расставим элементы как показано на рисунке ниже:

 

Рис. 4. 3. Расстановка элементов первой группы (OLE # 2)

 

Здесь представлены три кнопки Button, один, простой погашенный TextBox, как в предыдущей группе и два DataGridView. Также с панели инструментов было добавлен ещё один OpenFileDialog-элемент и один DataSet. Сразу оговоримся, для работы с добавлением данных через DataGridView база данных была переделана и название таблиц и столбцов были изменены (убраны символы кириллицы). Это связано с тем, что при работе с базой, в которой есть не английские символы в названиях таблиц (и столбцов) можно столкнуться с ошибками (не всегда). Сама же база осталась без изменений, Название: LWP 10- DB - OLE - Special . accdb. Содержание таблицы Main _ Table:

 

Функциональность блока будет следующей. Выбираем базу данных как в предыдущих случаях и жмём на Показать все записи. Всплывающее сообщение с результатами, за которым идёт добавление всех данных базы в левый (по рисунку 4. 3) DataGridView. Правый же будет загружен сразу при старте приложения (база будет взята по статическому пути D :\ LWP 10- DB - Special . accdb. Вносим изменения в ячейки (в правом DataGridViewv) и жмём на Сохранить записи. Результат можно будет увидеть перезагрузив приложение, либо открыв базу через Access. Изменения ячеек в левом DataGridView не будут нигде сохранены.

 

По порядку распишем Свойства каждого элемента:

 

Button:

(Name): B_OLE_2_Search
Text: Выбрать базу данных
Size: 200; 23

Button:

(Name): B_OLE_2_Read
Text: Прочитать все записи
Size: 200; 23

Button:

(Name): B_OLE_2_Save
Text: Сохранить записи
Size: 200; 23

TextBox:

(Name): TB_OLE_2_Path
ReadOnly: True

GroupBox:

(Name): GB_OLE_2
Text: OLE # 2

OpenFileDialog:

(Name): OFD_OLE_2
InitialDirectory: D:\
Filter База данных *.mdb|*.mdb|База данных *.accdb|*.accdb

DataGridView:

(Name): DataGridViewOLE

DataGridView:

(Name): DataGridViewOLE_S

DataSetw:

(Name): DataSetOLE

 

Теперь перейдём к коду. Найдём:

 

   String SQL_OLE_ADD = null; // Переменная для добавления данных

 

Добавим после:

 

   String ConnetionStringOLE2 = null;

   OleDbConnection ConnectionOLE2;

   String ConnetionStringOLE_S = null;

   OleDbConnection ConnectionOLE_S;

   OleDbDataAdapter DataAdapter_S;

 

Найдём:

 

       SQL_OLE = "SELECT * FROM [Главная таблица]";

 

Добавим после:

 

       TB_OLE_2_Path.Text = "D:\\LWP10-DB-OLE.accdb";

       B_OLE_2_Read.Enabled = false;

       DataGridViewOLE.DataMember = "Table"; // Указываем на тип подсписка для DataGridView

 

Событие Click кнопка Выбор базы данных:

   private void B_OLE_2_Search_Click(object sender, EventArgs e)

   {

 

          if (OFD_OLE_2.ShowDialog() == DialogResult.OK)

       {

           B_OLE_2_Read.Enabled = true;

           B_OLE_2_Save.Enabled = true;

           //TB_OLE_2_Path.Text = OFD_OLE_2.FileName;

           Directory.CreateDirectory(Path.GetDirectoryName(OFD_OLE_2.FileName) + @"\Копии"); // Создаём директорию под изменённые БД

           File.Copy(OFD_OLE_2.FileName, Path.GetDirectoryName(OFD_OLE_2.FileName) + @"\Копии\" + OFD_OLE_2.SafeFileName, true); // Копируем туда выбранную БД (перезаписываем, в случае обнаружения похожего файла)

           if (Path.GetDirectoryName(OFD_OLE_2.FileName) == Directory.GetDirectoryRoot(OFD_OLE_2.FileName)) // Проверяем путь, если находимся в корневой директории диска, режем один слеш

               TB_OLE_2_Path.Text = Path.GetDirectoryName(OFD_OLE_2.FileName) + @"Копии\" + OFD_OLE_2.SafeFileName;

           else

               TB_OLE_2_Path.Text = Path.GetDirectoryName(OFD_OLE_2.FileName) + @"\Копии\" + OFD_OLE_2.SafeFileName;

 

           if (Path.GetExtension(OFD_OLE_2.FileName) == ".mdb")

           {

               ConnetionStringOLE2 = "Provider=Microsoft.Jet.OLEDB.4.0;" +

                   @"Data Source=" + TB_OLE_2_Path.Text + "";

               MessageBox.Show("Выбрана база данных " + TB_OLE_2_Path.Text + " формата: *" + Path.GetExtension(TB_OLE_2_Path.Text) + "!", "Работа с базами данных (C#) :: OLE # 2");

           }

 

           if (Path.GetExtension(OFD_OLE_2.FileName) == ".accdb")

           {

               ConnetionStringOLE2 = "Provider=Microsoft.ACE.OLEDB.12.0;" +

                   @"Data Source=" + TB_OLE_2_Path.Text + "";

               MessageBox.Show("Выбрана база данных " + TB_OLE_2_Path.Text + " формата: *" + Path.GetExtension(TB_OLE_2_Path.Text) + "!", "Работа с базами данных (C#) :: OLE # 2");

           }

       }

   }

 

Событие Click кнопка Показать все записи:

 

   private void B_OLE_2_Read_Click(object sender, EventArgs e)

   {

       DataSetOLE.Clear(); // Очищаем DataSetOLE перед повторным заполнением из базы данных

       ConnectionOLE2 = new OleDbConnection(ConnetionStringOLE2);

 

       try

       {

           ConnectionOLE2.Open(); // Открываем соединение

           MessageBox.Show("Соединение с базой данных " + TB_OLE_2_Path.Text + " успешно открыто!", "Работа с базами данных (C#) :: OLE # 2");

       }

       catch (Exception ex)

       {

           MessageBox.Show("Невозможно открыть соединение с базой данных " + TB_OLE_2_Path.Text + " (" + ex.Message + ")!", "Работа с базами данных (C#) :: OLE # 2");

       }

       // Создаем объект DataAdapter и передаём ему данные запроса

       OleDbDataAdapter DataAdapter = new OleDbDataAdapter(); // DataAdapter - посредник между базой данных и DataSet

       DataAdapter.SelectCommand = new OleDbCommand(SQL_OLE, ConnectionOLE2);

       DataAdapter.Fill(DataSetOLE); // Данные из адаптера поступают в DataSet

       DataGridViewOLE.DataSource = DataSetOLE; // Связываем данные с элементом DataGridView

       // Закрываем соединение

       ConnectionOLE2.Close();

   }

 

Событие Click кнопка Сохранить записи:

 

   private void B_OLE_2_Save_Click(object sender, EventArgs e)

   {

 

         try

       {

           DataAdapter_S.Update((DataTable)DataGridViewOLE_S.DataSource);

           MessageBox.Show("Изменения в базе данных D:\\Копии\\LWP10-DB-OLE-Special.accdb успешно внесены!", "Работа с базами данных (C#) :: OLE # 2");

       }

       catch (Exception ex)

       {

           MessageBox.Show("Невозможно сохранить изменения в базе данных D:\\Копии\\LWP10-DB-OLE-Special.accdb (" + ex.Message + ")!", "Работа с базами данных (C#) :: OLE # 2");

       }

   }

 

Событие Load формы:

 

   private void LWP10Main_Load(object sender, EventArgs e)

   {

       Directory.CreateDirectory(@"D:\" + @"\Копии");

       File.Copy(@"D:\LWP10-DB-OLE-Special.accdb", @"D:\" + @"\Копии\" + @"LWP10-DB-OLE-Special.accdb", true);

 

       ConnetionStringOLE_S = "Provider=Microsoft.ACE.OLEDB.12.0;" +

           @"Data Source=D:\Копии\LWP10-DB-OLE-Special.accdb";

       ConnectionOLE_S = new OleDbConnection(ConnetionStringOLE_S);

 

       try

       {

           ConnectionOLE_S.Open(); // Открываем соединение

           MessageBox.Show("Соединение с базой данных D:\\Копии\\LWP10-DB-OLE-Special.accdb успешно открыто!", "Работа с базами данных (C#) :: OLE # 2");

       }

       catch (Exception ex)

       {

           MessageBox.Show("Невозможно открыть соединение с базой данных D:\\Копии\\LWP10-DB-OLE-Special.accdb (" + ex.Message + ")!", "Работа с базами данных (C#) :: OLE # 2");

       }

      DataTable DataTable_S = new DataTable();

       // Создаём команду

       OleDbCommand Command = new OleDbCommand("SELECT * FROM Main_Table", ConnectionOLE_S);

       // Создаём адаптер DataAdapter_S: посредник между базой данных и DataSet

       DataAdapter_S = new OleDbDataAdapter(Command);

       // Создаём построитель команд

       // Для адаптера становится доступной команда Update и другие команды

       OleDbCommandBuilder CommandBuilder = new OleDbCommandBuilder(DataAdapter_S);

       // Данные из адаптера поступают в DataTable_S

       DataAdapter_S.Fill(DataTable_S);

       // Связываем данные с элементом DataGridView

       DataGridViewOLE_S.DataSource = DataTable_S;

       // Закрываем соединение

       ConnectionOLE_S.Close();

   }

 

Компилируем приложение (Debug) и запускаем:

 

Рис. 4. 4. Окончательная работа блока: OLE # 2

 


Дата добавления: 2019-09-13; просмотров: 205; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!