
Програмне_забезпечення_ОС_ИНФ_5_сем / Метод_ПЗОС_сам
.docМіністерство освіти і науки, МОЛОДІ ТА СПОРТУ україни
Харківський Національний Університет Радіоелектроніки
методичні вказівки для самостійної роботи студентів
З дисципліни "Програмне забезпечення ОС "
Для студентів денної форми навчання для
спеціальності: 6.040303"Прикладна математика"
Зав. Кафедрою Інформатики Затверджено
Кафедрою Інформатики
Протокол №2
Від 29.09.2011 р.
ХАРКІВ 2011
Міністерство освіти і науки, МОЛОДІ ТА СПОРТУ україни
Харківський Національний Університет Радіоелектроніки
методичні вказівки для самостійної роботи студентів
З дисципліни " Програмне забезпечення ОС "
Для студентів денної форми навчання для
спеціальності: 6.040303"Прикладна математика"
ХАРКІВ 2011
вступ
Самостійна робота студентів є важливим фактором в оволодінні теоретичними, а особливо практичними навичками та знаннями по курсу. Під час самостійної роботи студенти повинні особливу увагу поділяти практичному оволодінню методами та засобами системного программування.
Системне програмування (СП) - вельми обширна область знань. Поруч з задачами розробки самих операційних систем (ОС), до СП відносять питання створення обслуговуючих програм і утиліт, програмування драйверів, BIOS, створення антивірусних програм, мережного програмного забезпечення та ін.
. РОЗРОБКА АПЛЕТІВ У JAVA З ГРАФІКОЮ
1.. Мета роботи
Вивчення практичних можливостей JAVA при створенні апплетів з створенням інтерфейсу .
2. Методичні вказівки до організації самостійної роботи студентів
1.4 Варіанти індивідуальних завдань
1. Розробити програму, яка будуватиме на екрані графіки функцій sin(x), cos(x), x2 за вибором користувача.
2. Розробити програму, яка дозволятиме користувачу рисувати на екрані прямокутник за допомогою миші. В програмі має бути можливість задавати колір прямокутника.
3. Розробити програму, яка дозволятиме користувачу будувати на екрані кругову діаграму з використанням даних введених користувачем.
4. Розробити програму, яка дозволятиме користувачу будувати на екрані стовпчасту діаграму з використанням даних введених користувачем.
5. Розробити програму, яка дозволятиме користувачу будувати на екрані багатокутники з використанням даних введених користувачем. Дані, які задає користувач: кількість кутів багатокутника та його колір.
6. Розробити програму, яка в двомірному просторі рисує декілька прямокутників та кіл. Надати користувачеві можливість вибирати один з цих об'єктів і переміщувати його по екрану та змінювати розмір за допомогою миші подібно векторним графічним редакторам.
7. Розробити програму, яка в двомірному просторі рисуватиме десять кіл, які переміщуються вертикально вниз по екрану та десять прямокутників, які переміщуються по екрану по горизонталі в обох напрямах.
8. Розробити програму, яка рисуватиме лінію, яка обертається за годинниковою стрілкою та другу лінію, яка обертатиметься проти годинникової стрілки.
19. Розробити програму, яка виводитиме на екран рядок тексту, який задає користувач під час роботи програми шрифтом, розміром та стилем, що обере користувач.
10. Розробити програму, яка рисуватиме декілька кіл, що довільно пересуватимуться по екрану. Коли вони наближатимуться до межі екрану чи один до одного, то кола повинні змінювати напрям руху на протилежний.
1.4 Контрольні запитання і завдання
1. Мета роботи Метою даної роботи є ознайомлення із середовищем розробки Visual Studio 2005 і бібліотекою компонентів Windows Forms. 2. Методичні вказівки з організації самостійної роботи У лабораторній роботі будуть розглянуті наступні питання: 1. Створення консольного додатку 2. Робота з масивами і колекціями 3. Введення / висновок 4. Створення програми Windows Forms 5. Створення нової форми, компоненти Windows Forms 6. Обробка подій 7. Підключення бібліотек 2.1. Створення консольного додатку Створимо в Visual Studio нове консольне додатки (File -> New -> Project -> Console Application, рис. 1) Рис. 1 - створення консольного застосування Вивчіть код, який згенерований середовищем розробки (Program.cs). Створений клас містить єдиний метод Main, який виконується при запуску програми. Масив args дозволяє отримати доступ до аргументів командного рядка. Для створення найпростішого додатка з розряду «Привіт світ» необхідно додати в метод Main наступний код: Console.Write ("Hellow world!"); Об'єкт Console надає можливість не тільки виводити інформацію (методи Write і WriteLine), але і вводити (метод Read). Основні типи C # мало відрізняються від тих, що відомі по Delphi / C + +: string, int, bool, char, double. 2.2. Робота з масивами і колекціями Масив - це структура даних, що містить кілька змінних одного і того ж типу. При оголошенні масиву необхідно обов'язково вказати цей тип (точно так само, як і в будь-якому іншому типизированном мовою): Type [] arrayName; Масиви в C # мають такі властивості: 1. Масив може бути одновимірним, багатовимірним і «рваним» (jagged, кожен елемент масиву в цьому випадку сам є масивом, причому розмірності «вкладених» масивів можуть не збігатися). 2. По-замовчуванню всі елементи числового масиву ініціалізувалися нулями, елементи масиву посилального типу ініціалізувалися значення null. 3. Індексація завжди починається з 0. 4. Можна створювати масиви елементів будь-якого типу. Нижче наведено приклад створення і ініціалізації масивів. / / Оголосити одновимірний масив int [] array1 = new int [5]; / / Оголошення і інізіалізація одновимірного масиву int [] array2 = new int [] {1, 3, 5, 7, 9}; / / Альтернативний синтаксис int [] array3 = {1, 2, 3, 4, 5, 6}; / / Двовимірний масив int [,] multiDimensionalArray1 = new int [2, 3]; / / Безпосередня ініціалізація двовимірного масиву int [,] multiDimensionalArray2 = {{1, 2, 3}, {4, 5, 6}}; В C # масиви насправді є об'єктами, а не просто виділеними ділянками пам'яті, як з C / C + +. Array є базовим абстрактним класом для всіх масивів. Відповідно, у кожного масиву є цілий набір методів і властивостей, успадкованих від цього класу. int [] array = {2, 4, 1, 6, 3}; Console.Write (array.Length); / / Змінює порядок проходження елементів на зворотний Array.Reverse (array); / / Сортує масив Array.Sort (array); В C # є ще один спеціальний тип масивів - «рвані» (jagged) масиви. Фактично це - масиви масивів. При цьому елементи масиву можуть мати різну розмірність (див. приклад коду ніжу). / / Оголошуємо «рваного» масиву з двох елементів int [] [] arr = new int [2] []; / / Ініціалізували arr [0] = new int [5] {1, 3, 5, 7, 9}; arr [1] = new int [4] {2, 4, 6, 8}; / / Відображається елементи масиву по одному for (int i = 0; i <arr.Length; i + +) { System.Console.Write ("Element ({0}):", i); for (int j = 0; j <arr [i]. Length; j + +) { System.Console.Write ("{0} {1}", arr [i] [j], j == (arr [i]. Length - 1)? "": ""); } System.Console.WriteLine (); } Для послідовної обробки всіх елементів масиву / колекції можна застосовувати наступну синтаксичну конструкцію: foreach (Type elem in <Array of Type>) { / / Робимо щось з elem } Так, наприклад, для виведення на консоль всіх елементів масиву можна скористатися наступним кодом: int [] X = {...}; foreach (int elem in X) { System.Console.WriteLine (elem); } Узагальнені колекції (Generics), що з'явилися в. NET Framework 2.0 фактично аналогічні стандартній бібліотеці шаблонів STL мови C + +. / / Список елеметов (в даному випадку рядків) List <string> goods = new List <string> (); goods.Add ("Молоко"); goods.Add ("Сир"); goods.Add ("Ковбаса"); goods.Add ("Сало"); goods.Add ("Хліб"); int i = goods.Count; / / Кількість елементів / / Виводимо елементи списку на консоль foreach (string s in goods) { Console.WriteLine (s); } / / Сортуємо елементи goods.Sort (); string [] arr = goods.ToArray (); / / Копіюємо в звичайний масив 2.3. Введення / висновок Всі об'єкти для роботи з файловою системою розташовані в просторі імен System.IO, відповідно на початку файлу необхідно додати директиву using System.IO. Опитування каталогу. string dirName = @ "c: \"; / / Об'єкт, який відповідає за каталог DirectoryInfo di = new DirectoryInfo (dirName); / / Виводимо на консоль список файлів, що містяться в каталозі foreach (FileInfo fi in di.GetFiles ()) { Console.Write (fi.Name + ""); } / / Виводимо на консоль список підкаталогів даного каталогу foreach (DirectoryInfo fi in di.GetDirectories ()) { Console.Write (fi.Name + ""); } Збереження масиву рядків у файл: / / Записуємо масив рядків у заданий файл, якщо файл існує, він буде перезаписаний string fileName = @ "c: \ temp \ sample.txt"; string [] fileContent = {"This string will be written to a file", "And this one too"}; File.WriteAllLines (fileName, fileContent); / / Прочитуємо наші рядки назад fileContent = File.ReadAllLines (fileName); Крім статичних методів класу File є ще великий набір потокових класів. / / Працюємо з фалів потоком аналогічно тому, як ми працюємо з консоллю string s = "Мама мила раму"; StreamWriter sw = new StreamWriter (fileName); sw.Write (s); sw.Close (); / / Закривати обов'язково! StreamReader sr = new StreamReader (fileName); string s1; while ((s1 = sr.ReadLine ())! = null) { Console.WriteLine (s1); } sr.Close (); / / Закривати обов'язково! StreamReader sr1 = new StreamReader (fileName); string s2 = sr1.ReadToEnd (); sr1.Close (); / / Закривати обов'язково! 2.4. Створення програми Windows Forms Створимо в Visual Studio новий проект (File -> New -> Project -> Windows Application). Кожне таке додатка спочатку містять одну форму. Форма має досить великий набір властивостей, який мало чим відрізняється від властивостей форми будь-якої іншої візуально бібліотеки. Кожна форма у додатку, що розробляється за допомогою графічного дизайнера, фактично складається з 3 або більше файлів: - <FormName>. Designer.cs - генерується самої середовищем Visual Studio, містить код, який відповідає за ініціалізацію та розміщення на формі візуальних компонентів; - <FormName>. Cs - в цьому файлі розташовані код, створюваний користувачем (обробники подій та ін.); - <FormName>. Resx - файл ресурсів, необхідний для підтримки локалізованих форм (обробляється самої середовищем, не вимагає редагування користувачем). Для запуску створеного програми необхідно увійти в меню Debugger і там вибрати Start Debugging (F5) для запуску в режимі відладки або Start Without Debugging (Ctrl + F5). Після першого запуску програми або після його компіляції (Build -> Build Solution (F7)) всі необхідні файли будуть поміщені в підкаталог bin того каталога, в який ви зберегли свій проект. Для перенесення програми на інший комп'ютер достатньо скопіювати вміст цього каталогу. Додати опис властивостей програми, налаштувань, ресурсів 2.5. Створення нової форми, візуальні компоненти Для додавання нової форми в проект необхідно вибрати пункт меню Project -> Add Windows Form. У діалоговому вікні можна вказати назву файлу, в якому буде збережена форма (фактично це буде ім'я форми). Щоб додати на форму компонентів (таких як кнопки, що випадають списки, текстові поля, мітки і т.п.) необхідно відкрити панель інструментів (Toolbox, рис. 2). Рис. 2 - палітра компонентів Поряд зі стандартними компонентами, присутні такі зручні компоненти, як DateTimePicker, MonthCalendar, TreeView, WebBrowser та ін. Зверніть увагу на те, як візуальний дизайнер допомагає в розмітці форми і взаємне розміщення компонентів. Багато компонентів (Label, Button, TextBox) мають властивість Text, яке дозволяє встановити / прочитати текстову рядок, який відображає компонент. Бібліотека Windows Forms також містить набір діалогів, аналогічний такому в бібліотеці VCL (див. приклад коду нижче). / / Діалог відкриття файлу OpenFileDialog ofd = new OpenFileDialog (); if (ofd.ShowDialog () == DialogResult.OK) { MessageBox.Show (ofd.FileName); } / / Збереження файлу SaveFileDialog sfd = new SaveFileDialog (); if (sfd.ShowDialog () == DialogResult.OK) { MessageBox.Show (sfd.FileName); } 2.6. Обробка подій У Windows Forms використовується традиційна подієва модель роботи додатку. Кожен компонент має досить великий набір подій, для кожного з яких може бути визначений обробник (рис. 3). Рис. 3 - список подій для компонента Button Подвійний клацання мишкою в полі поруч з назвою події дозволяє додати до цієї події обробник. При цьому відразу ж відкривається відповідний формі файл з кодом, курсор встановлюється в створеному методі. Наведений нижче код обробника натискання на кнопку button1 відкриває форму SecondForm. private void button1_Click (object sender, EventArgs e) { SecondForm form = new SecondForm (); form.Show (); } 2.7. Підключення бібліотек Для підключення бібліотеки до проекту необхідно вибрати пункт меню Project -> Add reference. У діалоговому вікні користувач може вибрати потрібну бібліотеку з GAC (Global assembly cache), компонент COM, бібліотеку, що зберігається на диску або проект (рис. 4). Рис. 4 - додавання посилання на бібліотеку Для того, щоб скористатися класами, визначеними в підключеної бібліотеці, необхідно або в коді вказувати повне ім'я класу (наприклад System.Data.SqlClient.SqlConnection для з'єднання з SQL Server-ом), або додати в початок файлу відповідне посилання на простір імен: using System.Data.SqlClient; Ті бібліотеки, на які посилається даний проект, відображаються в розділі References браузера проектів (Solution Explorer, рис. 5). Рис. 5 - список бібліотек, використовуваних в проекті 3. Порядок виконання роботи та індивідуальні завдання 3.1. Зміст звіту У звіті привести список використаних компонентів з описом основних властивостей, екранні форми розробленого програми та роздруківку вихідного коду (Program.cs для консольних додатків або файл коду форми для додатків Windows Forms). 3.2. Індивідуальні завдання 1. Створити консольне додаток, що дозволяє ввести з клавіатури список студентів у групі, сортує його і виводить в зворотному алфавітному порядку. 2. Створити додаток Windows Forms, що містить форму, з компонентами Edit, Button і ListBox. Забезпечити можливість редагування списку елементів в компоненті ListBox (додавання і видалення елементів). 3. Створити додаток Windows Forms, що містить форму з компонентом ListBox, в який необхідно вивести список файлів із заданого каталогу (компонент EditBox). 4. Створити консольний додаток або додаток Windows Forms, яке отримує від користувача шлях до каталогу і зчитує список файлів і директорій в цьому каталозі, об'єднує їх в один список, сортує його, змінює порядок на протилежний і записує у файл з заданим ім'ям. 5. Створити додаток Windows Forms, яке буде завантажувати вміст заданого текстового файлу в компонент EditBox (встановити властивість MultiLine в True). Забезпечити також можливість збереження відредагованого тексту. Скористатися компонентами SaveFileDialog і OpenFileDialog.
Доступ до даних та їх відображення 1. Мета роботи Ознайомлення з об'єктною моделлю ADO.NET, вивчення основних класів для доступу до даних. 2. Методичні вказівки з організації самостійної роботи У лабораторній роботі будуть розглянуті наступні завдання: 1. Підключення до бази даних. Поняття провайдера. 2. Виконання запиту та отримання результатів його виконання. 3. Візуальні компоненти для відображення даних. 4. Забезпечення можливості зміни даних. Як приклад слід вивчити демонстраційне додаток WorkingWithData1, яке містить реалізацію все описаних нижче способів роботи з даними. 2.1. Підключення до бази даних ADO.NET містить деяку кількість класів, специфічних для використовуваної СУБД. Ці класи реалізують безліч стандартних інтерфейсів, визначених у просторі імен System.Data, що дозволяє при необхідності, абстрагуватися від конкретної СУБД. Кожен провайдер, підтримуваний ADO.NET надає набір класів, що дозволяють здійснити підключення до БД, виконати запит / команду, отримати результат. Класи, специфічні для провайдера, розташовуються в просторі імен System.Data. <Provider>. Так, наприклад, класи, специфічні для OleDB визначені в просторі імен System.Data.OleDb. Нижче перераховані основні класи, з якими ми будемо працювати, загальний для всіх провайдерів інтерфейс і конкретні реалізації: • з'єднання з БД, інтерфейс IDbConnection (OleDbConnection, ODBCConnection, SqlConnection, OracleConnection); • команда (як правило, у формі SQL-запиту), інтерфейс IDbCommand (OleDbCommand, ODBCCommand, SqlCommand, OracleCommand); • доступ до набору даних, інтерфейс IDataReader (OleDbDataReader, ODBCDataReader, SqlDataReader, OracleDataReader); • адаптер даних (містить набір команд, що дозволяють завантажити набір даних, додавати до нього нові рядки, оновлювати або видаляти існуючі), інтерфейс IDataAdapter (OleDbDataAdapter, ODBCDataAdapter, SqlDataAdapter, OracleDataAdapter); • генератор запитів, загальний абстрактний клас DbCommandBuilder (OleDbCommandBuilder, ODBCCommandBuilder, SqlCommandBuilder, OracleCommandBuilder). Перш ніж ми зможемо виконати будь-яку команду (запит), необхідно створити підключення до СУБД. Кожне таке підключення описується рядком з'єднання. Структура цього рядка специфічна для провайдера. / / Підключення до БД MS Access, за допомогою провайдера OleDb OleDbConnection con = new OleDbConnection (@ "Provider = Microsoft.Jet.OLEDB.4.0; Data Source = <шлях до файлу БД>"); Структура рядка підключення до SQL Server-у дещо відрізняється: / / Використання SQL Server Authentication SqlConnection sq = new SqlConnection ( @ "Data Source = <Ім'я сервера>; User ID = <Ім'я користувача>;" + "Password = <Пароль>; Integrated Security = false; Initial Catalog = <Ім'я БД>"); / / Використання Windows authentication SqlConnection sq = new SqlConnection ( @ "Data Source = <Ім'я сервера>; Integrated Security = true; Initial Catalog = <Ім'я БД>"); Основні дії, які можна робити з підключенням - відкриття і закриття: / / Створюємо підключення IDbConnection con = new ...; / / Відкриваємо con.Open (); / / Виконуємо якісь дії, для яких потрібно було підключення / / Закриваємо con.Close (); 2.2. Виконання запиту та отримання результатів його виконання Для виконання якогось запиту до СУБД необхідно скористатися одним з класів, що реалізують інтерфейс IDbCommand. / / Створюємо підключення OleDbConnection con = new OleDbConnection (@ "...")) / / Створюємо запит, який поверне нам дані (всі записи з таблиці Clients) OleDbCommand com = new OleDbCommand ("SELECT * FROM Clients"); / / Також зазначаємо то з'єднання з базою, яке потрібно використовувати (con) com.Connection = con; Команда - це зовсім не обов'язково запит на вибірку даних. Це може бути будь-SQL-запит або виклик збереженої процедури. У будь-якому випадку цей запит буде оброблятися на сервері або провайдером та синтаксичні помилки в ньому будуть виявлені тільки в момент виконання. Після ініціалізації команди можна відправити її на виконання. При цьому є кілька методів, які можуть бути використані в залежності від того, що потрібно отримати в результаті: / / Виконує запит, повертає кількість порушених рядків int rowsAffected = command.ExecuteNonQuery (); / / Виконує запит і повертає першу колонку першого рядка результату. / / Все інше ігнорується і недоступно. object firstCell = command.ExecuteScalar (); / / Повертає DataReader, пов'язаний з результатом OleDbDataReader reader = command.ExecuteReader (); Слід звернути увагу на те, що для кожного провайдера існує своя реалізація класу DataReader, яка і повертається специфічною командою. Так, наприклад, SqlCommand поверне SqlDataReader. Якщо ж ви використовуєте базовий для всіх провайдерів інтерфейс IDbCommand, то в результаті виклику ExecuteReader () отримаєте об'єкт, який реалізує інтерфейс IDataReader. Далі для простоти, коли мова буде йти про об'єкти Connection, Command, DataReader, DataAdapter, CommandBuilder, буде матися на увазі набір специфічних для якогось провайдера класів (наприклад OleDbConnection, OleDbCommand, OleDbDataReader, OleDbDataAdapter, OleDbCommandBuilder), при цьому потрібно розуміти, що вироблені дії не залежать від обраного провайдера. Об'єкт DataReader дозволяє здійснювати послідовний доступ до рядків набору даних, який був отриманий в результаті виконання команди. Фактично, це статичний, односпрямований курсор, призначений тільки для читання. IDataReader rdr = command.ExecuteReader (); / / Читаємо всі записи по одній while (rdr.Read ()) { / / Звертаємося до полів поточного запису, робимо щось ... } rdr.Close (); Для звернення до полів поточного запису існують два способи: використання імені поля (при цьому доводиться вдаватися до явного перетворення типів) і використання індексу (порядкового номера поля) в поєднанні з одним із типізованих методів (GetInt32, GetBoolean, GetChar, GetDateTime, GetString і т . д.): / / Отримуємо значення поля Description string clientName1 = (string) rdr ["Description"]; / / Або так (без необхідності перетворювати тип): string clientName2 = rdr.GetString (rdr.GetOrdinal ("Description")); Зверніть увагу на наступне: 1. Необхідно явно відкрити з'єднання з БД до виконання команди (воно не відкривається автоматично). 2. Необхідно не забувати закривати об'єкт DataReader після завершення читання даних, тому що поки цей об'єкт явно не закрите, залишається активним курсор, який з ним пов'язаний, і відповідне підключення до БД. 2.3. Використання компонента DataGridView для відображення даних У тому випадку, коли необхідно не просто завантажити дані з БД і провести якісь обчислення, але й дати можливість користувачеві побачити ці дані у звичній табличній формі, необхідно використовувати підхід, дещо відрізняється від описаного вище. Крім об'єктів, що відповідають за фізичний доступ до даних (з'єднання, команда, курсор), в. NET є також набір об'єктів, що відповідають за логічний рівень. До таких належать: • стовпець (DataColumn) - визначення стовпця таблиці, що включає ім'я, тип даних, розмір; • рядок (DataRow) - набір значень, що відповідають рядку в таблиці; • обмеження (Constraint) - визначає правило, якому повинні відповідати дані в таблиці, відноситься до одного чи декількох об'єктів DataColumn; • таблиця (DataTable) - контейнер, що містить один або більше об'єктів DataColumn і, будучи, заповненим, містить колекцію об'єктів DataRow; • відношення (DataRelation) - визначає відносини між таблицями (зовнішній ключ); • набір даних (DataSet) - включає в себе безліч таблиць (DataTable) і відносин між ними (DataRelation). Одним з найбільш часто використовуваних об'єктів є DataTable. Багато в чому це пояснюється тим, що компонент DataGridView може безпосередньо відображати дані з об'єкта DataTable. Дуже корисною властивістю об'єкта DataTable є можливість завантаження даних з об'єкта, що реалізує інтерфейс IDataReader: / / Створюємо об'єкт DataTable, який може бути переданий / / Компоненту DataGridView в якості джерела даних DataTable table = new DataTable (); IDataReader rdr = comand.ExecuteReader (); table.Load (rdr); На цьому, власне, закінчується робота по завантаженню даних. Все, що залишилося - це зв'язати компонент DataGridView із заповненою таблицею: / / Вказуємо компоненту DataGridView на джерело даних GridView1.DataSource = table; Слід мати на увазі, що з об'єктом DataTable можна працювати як з набором записів навіть після того, як буде закрито підключення до бази, з якої ці записи були завантажені (тобто DataTable працює в отсоединенном режимі). При цьому можна модифікувати значення, що зберігаються в таблиці (вони будуть відображатися в компоненті DataGridView, але не вплинуть на дані, що зберігаються в БД): DataTable table = new DataTable (); IDataReader rdr = command.ExecureReader (); table.Load (rdr); foreach (DataRow row in table.Rows) { double balance = (double) row ["Balance"]; double discount = (double) row ["discount"]; row ["Balance"] = balance * discount; } Більш того, ніхто не вимагає, щоб об'єкт DataTable був пов'язаний (отримував дані) з БД: / / Створюємо DataTable table = new DataTable (); table.Columns.Add ("FirstName", typeof (string)); table.Columns.Add ("LastName", typeof (string)); table.Columns.Add ("Age", typeof (int)); / / Заповнюємо даними table.Rows.Add ("Іван", "Іванов", 35); table.Rows.Add ("Петро", "Петров", 45); / / Відображається GridView1.DataSource = table; 2.4. Забезпечення можливості зміни даних По-замовчуванню компонент DataGridView дозволяє редагувати дані, додавати нові і видаляти існуючі рядка. При цьому, однак, зміни не потраплять в БД, тому що об'єкт DataTable не зберігає інформації про те, звідки надійшли завантажені в нього дані і як їх слід оновлювати. Для того, щоб реалізувати редагування даних, необхідно явно задати команди, які дозволили б перенести зміни з об'єкта DataTable в БД. Реалізується це за допомогою об'єкта DataAdapter (детальний працюючий приклад можна знайти у додатку WorkingWithData1, DisplayData.cs, метод btnDataAdapter_Click): / / Створюємо підключення до БД OleDbConnection con = new OleDbConnection (@ "..."); / / Створюємо адаптер даних OleDbDataAdapter dataAdapter = new OleDbDataAdapter (); / / Визначаємо що саме потрібно отримати з БД OleDbCommand selectCommand = new OleDbCommand ("SELECT * FROM SomeTable"); selectCommand.Connection = con; dataAdapter.SelectCommand = selectCommand; / / Вказуємо що має відбуватися при додаванні нового рядка OleDbCommand insertCommand = new OleDbCommand ("INSERT INTO SomeTable ..."); insertCommand.Parameters.Add ("@ Par1", OleDbType.VarChar, 50, "<FieldName>"); / / Додаємо всі інші параметри ... insertCommand.Connection = con; dataAdapter.InsertCommand = insertCommand; / / Спосіб поновлення даних OleDbCommand updateCommand = new OleDbCommand ("UPDATE SomeTable SET ..."); / / Додаємо всі параметри ... updateCommand.Connection = con; dataAdapter.UpdateCommand = updateCommand; / / Реакція на видалення рядка OleDbCommand deleteCommand = new OleDbCommand ("DELETE FROM SomeTable ..."); / / Додаємо параметри ... deleteCommand.Connection = con; dataAdapter.DeleteCommand = deleteCommand; / / Заповнюємо таблицю даними за допомогою адаптера DataTable dataTableToFill = new DataTable (""); dataAdapter.Fill (dataTableToFill); / / Робимо щось далі Після заповнення таблиці даними, необхідно зберегти посилання на об'єкт DataAdapter, т.к. він знадобиться для синхронізації оновлень між об'єктом DataTable і БД: OleDbDataAdapter dataAdapter = new OleDbDataAdapter (); DataTable table = new DataTable (); / / Ініціалізували DataAdapter ... dataAdapter.Fill (table); / / Робимо щось з даними (додаємо, видаляємо, редагуємо рядки ... / / Вносимо зміни з DataTable в базу даних dataAdapter.Update (table); Задавати вручну всі команди для внесення змін до БД м'яко кажучи незручно, тому в. NET був доданий спеціальний об'єкт, який може зробити це за нас - CommandBuilder: / / Створюємо адаптер даних OleDbDataAdapter clientsDataAdapter = new OleDbDataAdapter (); / / Визначаємо що саме потрібно отримати з БД OleDbCommand selectCommand = new OleDbCommand ("SELECT * FROM SomeTable"); selectCommand.Connection = con; clientsDataAdapter.SelectCommand = selectCommand; / / Insert, Update, Delete згенерує CommandBuilder OleDbCommandBuilder commandBuilder = new OleDbCommandBuilder (clientsDataAdapter); Зверніть увагу на наступне: 1. При роботі з об'єктом DataAdapter необов'язково явно відкривати з'єднання. 2. Ви повинні явно вказати з'єднання для кожної команди. При цьому, в принципі, в кожному випадку це може бути різне з'єднання (наприклад, можна вносити зміни в іншу БД). 3. Необхідно явним чином вносити зміни до БД за допомогою виклику методу Update, якому потрібно передати об'єкт DataTable, які раніше був заповнений тим же адаптером. 4. При використанні об'єкта CommandBuilder автоматично генеруються тільки ті команди, які явно не задані (тобто якщо попередньо визначити команду для Insert, вона не буде перевизначена після підключення CommandBuilder-а). 5. Відношення між об'єктами DataAdapter і CommadnBuilder - один до одного (не більше одного CommandBuilder-а на DataAdapter і не більше одного DataAdapter-а на CommandBuilder). 3. Порядок виконання роботи та індивідуальні завдання 3.1. Зміст звіту У звіті привести список використаних об'єктів і компонентів з описом основних властивостей, екранні форми розробленого програми та роздруківку вихідного коду. 3.2. Індивідуальні завдання Перед тим, як приступати до виконання свого варіанту, необхідно створити БД MS Access (повторення не допускаються!), Що містить 3-4 таблиці, зв'язані між собою (предметна область - довільна). 1. Забезпечити можливість збереження версії запису в одній з таблиць. Для цього в таблиці створити спеціальне поле, значення якого буде збільшуватися на 1 при кожному оновленні запису. Заборонити явне редагування значення цього поля. Скористатися об'єктами DataAdapter, CommandBuilder, DataTable і компонентом DataGridView. 2. У створеній БД для однієї з таблиць забезпечити підтримку логічного видалення записів - при видаленні запису вона певним чином позначається (наприклад, в поле IsDeleted заноситься 1) і її фізичного видалення не відбувається. Забезпечити можливість перегляду видалених записів (в окремому компоненті DataGridView). Скористатися об'єктами DataAdapter, CommandBuilder, DataTable і компонентом DataGridView. 3. У створеній БД забезпечити можливість ведення протоколу змін для однієї з таблиць - при додаванні записів в таблицю А, необхідно додати запис в таблицю Б, в якій буде зберігатися інформація про час проведення операції. Забезпечити можливість перегляду таблиць А і Б. 4. Створити програму, яка б програмно реалізовувало підтримку посилальної цілісності даних в двох таблицях (оновлювало б посилання на головну таблицю в підпорядкованої таблиці в разі редагування значення первинного ключа). Скористатися об'єктами DataAdapter, CommandBuilder, DataTable і компонентом DataGridView. 5. У створеній БД повинна бути таблиця, в якій є строкове поле (припустимо StringField). Завантажити дані з цієї таблиці за допомогою DataReader-а в компонент DataTable. При цьому в DataTable необхідно створити додаткове поле, в яке необхідно занести довжину даних в поле StringField поточного рядка. Показати дані в компоненті DataGridView. Примітка: необхідно звертатися до даних за допомогою об'єкта DataReader, а об'єкт DataTable створювати та заповнювати програмно, при додаванні нового рядка розраховувати довжину значення в поле StringField і заносити її в нове поле.