69075

ТЕХНОЛОГІЯ ADO .NET. ВІД’ЄДНАНІ ОБ’ЄКТИ

Лекция

Информатика, кибернетика и программирование

В попередній лекції ми розглядали роботу з даними через приєднані об’єкти, тобто через постійне з’єднання з джерелом даних. Програма відкривала з’єднання з базою даних і не закривала його принаймні до завершення роботи з джерелом даних. В цей час з’єднання з джерелом підтримувалося постійно.

Украинкский

2014-09-29

76.35 KB

3 чел.

9

ЛЕКЦІЯ 11. ТЕХНОЛОГІЯ ADO .NET. ВІД'ЄДНАНІ ОБ'ЄКТИ

План

11.1. Об’єктна модель ADO .NET. Від'єднані об'єкти

11.2. Заповнення набору даних. Класи DataAdapter і DataSet 

11.3. Відображення. Прив'язка даних до елементів управління форми

11.4. Переміщення по набору даних. Клас CurrencyManager

11.5. Змінювання даних (додавання, видалення, оновлення)

11.1. Об’єктна модель ADO .NET. Від'єднані об'єкти

В попередній лекції ми розглядали роботу з даними через приєднані об'єкти, тобто через постійне з'єднання з джерелом даних. Програма відкривала з'єднання з базою даних і не закривала його принаймні до завершення роботи з джерелом даних. В цей час з'єднання з джерелом підтримувалося постійно.

Недоліки такого підходу стали виявлятися після появи програм, орієнтованих на Інтернет.

З'єднання з базою даних вимагають виділення системних ресурсів, і якщо база даних розташована на сервері, то при великій кількості клієнтів це може бути критичним для сервера.

В ADO .NET підтримується інша модель доступу – доступ до від'єднаних даних. При цьому з'єднання встановлюється лише на той час, який необхідний для проведення певної операції над базою даних.

Нижче перелічені від'єднані об'єкти доступу до даних.

  1.  Об'єкт DataSet є від'єднаним набором даних, який може розглядатися як контейнер для об'єктів DataTable. DataSet дозволяє організовувати усередині себе структуру, яка повністю відповідає реальній структурі таблиць і зв'язків між ними в базі даних.
  2.  Об'єкт DataTable дозволяє переглядати дані у вигляді наборів записів і стовпчиків.
  3.  Об'єкт DataColumn є стопчиком об'єкту DataTable. Набір всіх стовпчиків об'єкту DataTable є колекцією Columns.
  4.  Об'єкт DataRow є рядком об'єкту DataTable. Набір всіх рядків цього об'єкту є колекцією Rows.
  5.  Об'єкт DataView призначений для організації можливості перегляду вмісту DataTable різними способами. Це відноситься до таких операцій, як сортування і фільтрація записів.
  6.  Об'єкт DataRelation є описом зв'язків між таблицями реляційної бази даних. Він надається об'єктом DataSet і дозволяє організовувати взаємозв'язки між таблицями від'єднаного набору даних об'єкту DataSet.

Основною ідеєю використання від'єднаних наборів даних є зміни алгоритмів взаємодії програми з базою даних за рахунок підключення до набору даних, виконання запиту і створення копії даних на стороні клієнта, відключення від БД, здійснення маніпуляцій з даними на стороні клієнта, при необхідності внесення змін до бази даних, підключення до неї, передача змін і відключення. Таким чином, всі основні маніпуляції з даними відбуваються у від'єднаному наборі даних, що є копією даних, які зберігаються в базі даних, а внесення змін відбувається в одній пакетній операції. Все це зменшує час, протягом якого має бути відкрите з'єднання, прискорює роботу і спрощує логіку взаємодії програми з даними.

Клас DataSet

Використання об'єкту DataSet у ряді випадків є більш ефективним, ніж об'єкту DataReader. Найбільш типовими ситуаціями, в яких рекомендується застосовувати об'єкт DataSet, є:

  1.  Необхідність збереження даних на диск. DataSet дозволяє легко зберігати дані у файлі XML. При цьому можливі варіанти збереження лише даних, лише структури даних, або і того і іншого.
  2.  Необхідність організації навігації по набору даних в двох напрямах. Як уже згадувалося, DataReader забезпечує переміщення по набору лише вперед. З допомогою ж DataSet можлива організація перегляду даних по одному запису вперед і назад.
  3.  Необхідність прив'язки декількох елементів управління до одного набору даних. DataSet, на відміну від DataReader, містить засоби організації сортування і фільтрації даних.

Клас DataSet має багато властивостей, які доступні з вікна властивостей Visual Studio та методів. Деякі методи, які будуть використані в прикладі наведено в таблиці   11.1.

Таблиця 11.1 - Деякі методи класу DataSet

Метод

Опис

AcceptChanges()

Зберігає всі зміни, внесені до класу DataSet після його завантаження або після останнього виклику методу AcceptChanges

Clear()

Видаляє з класу DataSet будь-які дані шляхом видалення всіх рядків у всіх таблицях

GetChanges()

Отримує копію класу DataSet, що містить всі зміни, внесені після його завантаження або після останнього виклику методу AcceptChanges

Клас DataAdapter

Для вибору даних з бази даних і наповнення ними об'єкту DataSet необхідно використовувати об'єкт DataAdapter, який дозволяє оновлювати дані БД на основі внесених до DataSet змін.

Таким чином, DataAdapter є сполучною ланкою між базою даних і DataSet. Точніше, він зв'язує базу даних і об'єкт DataTable, розташований усередині DataSet. DataAdapter є приєднаним об'єктом, так як виконує SQL-запити до бази даних.

DataAdapter містить три основні методи, що дозволяють йому виконувати всі необхідні операції, пов'язані з вибором і оновленням даних (табл. 11.2).

Таблиця 11.2 - Методи класу DataAdapter

Метод

Опис

Fill()

Виконання запиту типу Select, визначеного у властивості SelectCommand і додавання таблиці, що отримується в результаті запиту в DataSet.

FillSchema()

Виконання запиту типу Select, текст якого розташований у властивості SelectCommand і додавання таблиці, що містить лише структуру даних, отриманих в результаті виконання запиту в DataSet.

Update()

Застосовує всі зміни, внесені до DataTable до джерела даних. При цьому виконуються команди вставки, оновлення і видалення, розташовані у властивостях InsertCommand, UpdateCommand, DeleteCommand.

11.2. Заповнення набору даних. Класи DataSet і DataAdapter

Використання об'єктів DataSet і DataAdapter розглянемо на прикладі вибору даних з БД, заповнення DataSet і відображення даних на формі.

Будемо використовувати ту саму таблицю Student. В цьому прикладі всі дії виконуються програмуванням, без застосування візуальних засобів. Ми побачимо, що обсяг коду не набагато більший, але ми досягаємо гнучкості програми, завдяки застосуванню програмованих об'єктів.

Нам потрібно розробити програму у вигляді Windows Form Application, яка відображає по одному запису з таблиці і виконує типові дії з даними: переміщення по набору даних вперед і назад, додавання, оновлення, та видалення.

Почнемо...

Запустіть Visual Studio і створіть рішення типу Windows Form Application.

На формі розмістіть елементи Label: Код студента, Група, Прізвище, Рейтинг.

Додайте три елементи TextBox: txt_ID, txtGroup, txtName, txtRating. В ці текстові поля будемо виводити дані про студентів з таблиці Student.

Додайте до форми елементи Button, як зображено на рис. 11.1. Властивостям Name і Text призначте значення як наведено в таблиці 11.3.

Для відображення номерів запитів додайте на форму ще один елемент Label (Label5).

Рис. 11.1. Форма для роботи з таблицею Student в режимі проектування

Таблиця 11.3 - Призначення програмних кнопок

Властивість

Призначення

(Name)

Text

btnFirst

|<

Відображення першого запису таблиці

btnPrev

<

Відображення попереднього запису таблиці

btnAdd

Додати

Додавання пустого запису і очищення текстових полів для введення нового запису

btnSave

Зберегти

Збереження змін в базі даних

btnUpdate

Зберегти

Оновлення запису в таблицю

btnDelete

Видалити

Видалення запису з таблиці

btnNext

>

Відображення наступного запису таблиці

btnLast

>|

Відображення останнього запису таблиці

Класи для роботи з базами даних SQL Server 2005, SQLEXPRESS розміщені в просторі імен System.Data.SqlClient, тому цей простір потрібно підключити директивою using.

using System.Data.SqlClient;

Тепер переходимо до програмування доступу до даних. Насамперед, необхідно встановити з'єднання з базою даних. Для цього використовується приєднаний об'єкт Connection.

Змінна strConnection повинна бути визначена на рівні класу.

      SqlConnection Connection

       {

           get

           {

               if (con == null)

               {

                   con = new SqlConnection(strConnection);

               }

               if (con.State != ConnectionState.Open)

               {

                   con.Open();

               }

               return con;

           }

       }

     SqlConnection con;  .//con – об'єкт типу SqlConnection

//рядок з'єднання з сервером

       string strConnection = "Data Source=..\\SQLEXPRESS;Initial Catalog=labDB;Integrated Security=True";

Замісь ".. " в Data Source вкажіть правильний сервер, наприклад,

       string strConnection = "Data Source=user22\\SQLEXPRESS;Initial Catalog=labDB;Integrated Security=True";

Об'єкти класів SqlDataAdapter і DataSet використовуються в різних методах форми, тому створимо їх на рівні класу.

public partial class Form1 : Form

   {

     //глобальні змінні на рівні класу Form

       //створення об'єкту da класу SqlDataAdapter

       SqlDataAdapter da = new SqlDataAdapter();

       //створення об'єкту ds класу DataSet

       DataSet ds = new DataSet();

....................................

Приєднання до бази даних, вибір даних з таблиці в набір DataSet, прив'язка до текстових полів форми виконується при завантаженні форми, тому ці команди будемо розміщувати в обробнику події форми Form_Load.

Як і у випадку використання візуальних засобів, потрібно виконати такі дії:

1. встановити з'єднання з базою даних;

2. створити рядок з запитом       

string sqlString = "Select * From Student";

3. створити об'єкт класу SqlCommand для з'єднання і вибрати дані відповідно до запиту (в нашому прикладі вибираються всі записи з таблиці).

           SqlCommand command = new SqlCommand(sqlString, con);

           da.SelectCommand = command;

4.  Створити і заповнити об'єкт ds класу DataSet

           da.Fill(ds, "Student");

5. "прив'язати" вибрані поля з DataSet до текстових полів для відображення на формі.

З цього прикладу видно, що метод Fill об'єкту da, у якості параметра використовує ім'я об'єкту DataSet, в який необхідно помістити дані, отримані в результаті виконання запиту, визначеного в рядку sqlString. У другому параметрі можна вказати ім'я, яке буде зіставлено з таблицею, створеною в DataSet (таблицею "Student").

11.3. Відображення. Прив'язка даних до елементів управління форми

Більшість елементів управління WinForm підтримують прив'язку даних. При цьому прив'язка може бути як даних з одним значенням, так і з множинними значеннями. Прив'язка з одним значенням означає, що елемент управління може відображати одне значення, вибране з джерела даних. Такі принципи використовуються елементами управління TextBox, Image. Прив'язка з множинними значеннями означає, що елемент управління може відображати декілька значень, вибраних з джерела даних. Елементи управління, що підтримують прив'язку з множинними значеннями, будуються на основі списків і таблиць. Типовими представниками таких елементів управління є ListBox і GridView.

В нашому прикладі потрібна прив'язка з одним значенням, тобто, в текстових полях повинні відображатися поля одного запису. Для цього використовується властивість тестового поля DataBindings. Метод Add додає до  тестового поля відповідне значення з набору Data Set. Додамо в метод Form1_Load код:

           //прив'язка до полів форми

           txt_ID.DataBindings.Add("Text", ds, "Student.Student_ID");

           txtGroup.DataBindings.Add("Text", ds, "Student.Group1");

           txtName.DataBindings.Add("Text", ds, "Student.Student_name");

     txtRating.DataBindings.Add("Text", ds, "Student.Rating");

11.4. Переміщення по набору даних. Клас CurrencyManager

При виводі даних у вигляді окремих записів необхідно реалізувати можливість переміщення по набору. Це можна зробити за допомогою класу CurrencyManager, що забезпечує зв’язок з даними.

Клас CurrencyManager є похідним від класу BindingManagerBase. Ми будемо його використовувати для переміщення по набору даних і відображення чергового запису на формі. Деякі властивості класу наведено в таблиці 11.4.

Таблиця 11.4 – Основні властивості класу CurrencyManager

Властивість

Призначення

Current

Отримує поточний елемент в списку

Bindings

Отримує колекцію прив'язок

Count

Отримує число елементів в наборі

Position

Отримує або задає поточну позицію в списку

Створіть на рівні форми об'єкт цього класу.

    CurrencyManager cmRecords;

В методі Load_Form зв'яжіть об'єкт cmRecords з набором Data Set за допомогою методу BindingContext, а елементу label5 призначте текстовий рядок, який показує, що це перший запис набору даних.

     cmRecords = (CurrencyManager)BindingContext[ds, "Student"];

     label5.Text = "Запис " + (cmRecords.Position + 1).ToString() + "  з " + cmRecords.Count.ToString();

В кінці потрібно закрити з'єднання з базою даних.

Тепер метод Form1_Load буде таким, як показано в лістингу 11.1.

     Лістинг 11.1.

 private void Form1_Load(object sender, EventArgs e)

       {

           //з'єднання в сервером і базою даних

           con = Connection;

           //формування SQL запиту

           string sqlString = "Select * From Student";

           SqlCommand command = new SqlCommand(sqlString, con);

           da.SelectCommand = command;

         //заповнення ds

           da.Fill(ds, "Student");

           //прив'язка до полів форми

           txt_ID.DataBindings.Add("Text", ds, "Student.Student_ID");

           txtGroup.DataBindings.Add("Text", ds, "Student.Group1");

           txtName.DataBindings.Add("Text", ds, "Student.Student_name");

           txtRating.DataBindings.Add("Text", ds, "Student.Rating");

           cmRecords = (CurrencyManager)BindingContext[ds, "Student"];

           label5.Text = "Запис " + (cmRecords.Position + 1).ToString() + "  з " + cmRecords.Count.ToString();

           con.Close();

  }

Реалізуємо обробники кнопок переміщення по набору даних,  використовуючи властивість Position.

     Лістинг 11.2.

       private void btnFirst_Click(object sender, EventArgs e)

       {

 // First Record

           cmRecords.Position = 0;

           label5.Text = "Запис " + (cmRecords.Position+1).ToString() + "  з " + cmRecords.Count.ToString();

       }

       private void btnPrev_Click(object sender, EventArgs e)

       {

 // Prev Record

           cmRecords.Position--;

           label5.Text = "Запис " + (cmRecords.Position + 1).ToString() + "  з " + cmRecords.Count.ToString();

       }

       private void btnNext_Click(object sender, EventArgs e)

       {

           //Next Record

           cmRecords.Position++;

           label5.Text = "Запис " + (cmRecords.Position + 1).ToString() + "  з " + cmRecords.Count.ToString();

       }

       private void btnLast_Click(object sender, EventArgs e)

       {

  //Last Record

           cmRecords.Position = cmRecords.Count - 1;

           label5.Text = "Запис " + (cmRecords.Position + 1).ToString() + "  з " + cmRecords.Count.ToString();

11.5. Змінювання даних (додавання, видалення, оновлення)

Реалізуйте в обробниках кнопок операції маніпулювання даними в наборі даних. Метод AddNew() об'єкту CurrencyManager вставляє новий запис в набір Data Set та очищує текстові поля на формі.

      private void btnAdd_Click(object sender, EventArgs e)

       {

           //Add new record

           cmRecords.AddNew();

        }

Для обробника кнопки "Видалити" використовуємо вбудований метод RemoveAt, причому якщо на формі не буде записів, то викликаємо вікно попередження:

       private void btnDelete_Click(object sender, EventArgs e)

       {

           //Delete

           if (cmRecords.Count > 0) cmRecords.RemoveAt(cmRecords.Position);

           else

           { MessageBox.Show("Немає запису для видалення!", "Видалення запису", MessageBoxButtons.OK, MessageBoxIcon.Error); }

       }

Запускаємо програму. Тепер можна додавати і видаляти записи — проте всі зроблені зміни зберігаються в об'єкті DataSet і не передаються в базу даних.

В обробнику кнопки "Оновити" створюємо новий об'єкт DataSet changes, в який будуть записуватися всі зміни старого DataSet ds. Методу Update об'єкту DataAdapter1 передаємо новий DataSet changes і, нарешті, викликаємо метод AcceptChanges для підтвердження змін. Додамо блок обробки помилок для перехоплення можливих помилок збереження даних.

     Лістинг 11.3.

       private void btnUpdate_Click(object sender, EventArgs e)

       {

           //

          if (ds.HasChanges())

    try

     {

      DataSet changes = ds.GetChanges();

      da.Update(changes);

      ds.AcceptChanges();

    }

    catch(Exception ex)

    {

    MessageBox.Show(ex.Message, "Невдале оновлення", MessageBoxButtons.OK,MessageBoxIcon.Error);

    }

  else    

 MessageBox.Show("Немає записів для оновлення","Оновлення записів", MessageBoxButtons.OK,MessageBoxIcon.Information);

    }

Тепер, якщо ми спробуємо внести зміни, не перейшовши до наступного запису, з'явиться вікно попередження "Немає записів для оновлення". Більш того, якщо зв'язок з базою даних виявиться неможливим (наприклад, вона заблокована), то у вікні "Невдале оновлення" вийде повідомлення з кодом помилки. Для того, щоб користувачеві не доводилося замислюватися про роботу CurrencyManager, додамо в код кнопки "Додати" відключення інших кнопок на час редагування запису:

     Лістинг 11.4.

       private void btnAdd_Click(object sender, EventArgs e)

       {

           //Add new record

           cmRecords.AddNew();

           btnFirst.Enabled = false;

           btnLast.Enabled = false;

           btnNext.Enabled = false;

           btnPrev.Enabled = false;

           btnDelete.Enabled = false;

           btnUpdate.Enabled = false;

        }

Для повернення до звичайного режиму додамо на форму кнопку "Зберегти", яка повертатиме позицію на перший запис і активізує інші кнопки:

       private void btnSave_Click(object sender, EventArgs e)

       {

           //Save

           cmRecords.Position = 0;

           btnFirst.Enabled = true;

           btnLast.Enabled = true;

           btnNext.Enabled = true;

           btnPrev.Enabled = true;

           btnDelete.Enabled = true;

           btnUpdate.Enabled = true;

       }

Тепер ми можемо проглядати, додавати і видаляти записи з таблиці Student (рис. 11.2).

Рис. 11.2. Форма при виконанні

Висновки

Використання від'єднаних об'єктів доступу до даних дозволяє створювати ефективні і масштабовані розподілені програмні системи для роботи з базами даних. Головний об'єкт – DataSet є від'єднаним набором даних в пам'яті, структура якого відповідає реальній структурі таблиць і зв'язків між ними в базі даних. Для заповнення набору даних використовується об'єкт DataAdapter, який є сполучною ланкою між базою даних і набором DataSet.

Для переміщення по набору даних призначений клас CurrencyManager, який забезпечує зв’язок з даними.

Контрольні запитання і завдання для самостійного виконання

1. Яка різниця між приєднаними об’єктами і від'єднаними?

2. Чому в ADO .NET підтримується модель доступу до від'єднаних даних?

3. Дайте характеристику від'єднаних об’єктів доступу до даних.

4. Яке призначення мтода Fill() і до якого класу він відноситься?

5. Які основні властивості має клас DataSet?

6. Яке призначення і основні методи класу DataAdapter?

7. Який метод потрібно викликати для заповнення набору даних?

8. Яке призначення властивості DataBindings?

9. Які основні властивості має клас CurrencyManager?

10. Який метод класу DataAdapter призначений для оновлення даних в базі даних?


 

А также другие работы, которые могут Вас заинтересовать

27582. Грабеж и его признаки 35.5 KB
  Понятие насильственного грабежа его отличие от разбоя ст. Объект грабежа 161 отношения собственности при квалифицирующих признаках грабежа появляется дополнительный факультативный объект телесная неприкосновенность потерпевшего. Кроме того следует учитывать момент окончания этих преступлений материальный состав грабежа предполагает завладение чужим имуществом тогда как состав разбоя нет. При разграничении разбоя и грабежа важен и способ действия виновного применение ОРУЖИЯ или предметов используемых в качестве оружия всегда...
27583. Действие уголовного закона во времени. Обратная сила уголовного закона и её пределы. Действие уголовного закона в пространстве, его принципы (территориальный, гражданства, реальный, универсальный). Выдача лиц, совершивших преступление 42 KB
  Уголовный закон это нормативноправовой акт принимаемый высшими органами государственной власти и состоящий из взаимосвязанных норм определяющих основания и принципы уголовной ответственности а также какие деяния признаются преступлениями порядок назначения наказания за их совершение либо в определенных случаях указывающих условия для освобождения от уголовной ответственности и наказания. Законом усиливающем наказание является закон вводящий в санкцию статьи Особенной части более суровый вид наказания чем был предусмотрен. Усиление...
27585. Заведомо ложные показание, заключение эксперта или неправильный перевод (ст. 307 УК). Заведомо ложный донос (ст. 306 УК) и его отличие от клеветы (ст. 129 УК) 30.5 KB
  Объективная сторона данного преступления выражается в том что названные в ч. Комментируемое деяние становится квалифицированным если оно соединено с обвинением лица в совершении тяжкого или особо тяжкого преступления. Круг субъектов данного преступления определен в самой норме это свидетель потерпевший эксперт специалист и переводчик. Подозреваемый обвиняемый и подсудимый не могут быть привлечены к ответственности Субъективная сторона этого преступления характеризуется только прямым умыслом.
27587. Задачи и функции (охранительная и регулятивная) уголовного права. Принципы уголовного права 29 KB
  Задачи и функции охранительная и регулятивная уголовного права. Принципы уголовного права. Задачи уголовного права сформулированы в ст. Задачи уголовного права реализуются в процессе осуществления основных функций данной отрасли законодательства 1 Предупредительная регулятивная функция заключается в установлении наказания тем самым предупреждая граждан об ответственности в случае совершения преступления.
27589. Задержание лица, совершившего преступление. Основания для задержания и условия правомерности действий по его задержанию. Отличие причинения вреда при задержании преступника от необходимой обороны 29 KB
  Задержание лица совершившего преступление. В соответствии с законом не является преступлением причинение вреда лицу совершившему преступление при его задержании для доставления органам власти и пресечения возможности совершения им новых преступлений если иными средствами задержать такое лицо не представилось возможным и при этом причиненный вред не превысил пределов необходимости. 91 УПК РФ: 1 если лицо застигнуто при совершении преступления или непосредственно после его совершения; 2 потерпевшие или очевидцы укажут на данное лицо как...