Программирование / Заочники / 2 семестр / Методичка_ч3_Урок5
.pdfУрок 5: Введение в базы данных.
Основная цель урока.
1.Научиться создавать и подключать базу данных к проекту Windows Forms.
2.Научиться пользоваться компонентами DataSet и TableAdapter.
3.Продолжить изучение лямбда-выражений.
Учебное задание 5.1.
Создать базу данных, которая будет хранить расписание учебных занятий, и
выводить расписание на сегодняшний день.
Технология выполнения учебного задания 5.1.
Шаг 1. Создайте новый проект Windows Forms, назовите его Lab51.
Шаг 2. Создадим новую базу данных и подключимся к ней. Если использовать
Access, то база данных создаётся во внешней программе (MS Access, входит в
Microsoft Office). Для большей независимости от внешних компонентов в этой работе будет использоваться база данных Microsoft Compact 3.5. Создание и заполнение таблиц этой базы данных (далее БД) может вестись прямо из Visual Studio.
Выберите из меню Данные -> Добавить новый источник данных… , далее выбираете « База данных», в следующем окне выбираете « Набор данных» и в следующем окне нажимаете на кнопку « Создать подключение…».
В открывшемся окне у поля « Источник данных» нажимаете на кнопку « Изменить…»
и из открывшегося окна выбираете «Microsoft SQL Server Compact 3.5», нажимаете ОК.
В поле « База данных» пишете имя базы данных db(имя БД может быть любым, но
для выполнения этой работы важно указать именно db). |
|
Т.к. база данных ещё не создана, нажимаете кнопку « Создать…», |
после чего в |
появившимся окне выбираете язык « Россия – Русский», пароль |
не ставите, |
нажимаете ОК. |
|
Рисунок 1. Окно создания новой базы данных
Рисунок 2. Окно подключение к базе данных(после создания)
Затем поставьте галочку |
у чекбокса « Сохранить пароль», |
нажмите кнопку |
« Проверить подключение», |
затем нажмите ОК. |
|
В окне « Мастер настройки источника данных» нажмите « Далее». |
В появившемся |
|
окне предложат скопировать базу данных в локальную папку с проектов, выберите
« Да» ( рисунок 3).
Рисунок 3. Копирование базы данных в локальную папку проекта Затем нажмите « Далее» и затем « Готово».
Теперь у вас есть новая база данных (пока что пустая, без таблиц и без данных),
подключенная к проекту.
Шаг 3. Теперь создадим новую таблицу « Расписание». Для этого откройте окно
« Обозреватель серверов» ( если оно не открыто по умолчанию), для этого выберите из меню « Вид» пункт « Обозреватель серверов».
Рисунок 4. Обозреватель серверов Для создания новой таблицы кликните правым кликом на папке « Таблицы» и
выберите пункт « Создать таблицу». В появившемся окне задаётся имя и структура таблицы (названия полей таблицы и их типы). Добавьте новые поля в таблицу, как показано на рисунке 5. Поле ID_Расписание должно быть ключевым и свойство
« Идентификация» должно иметь значение true (благодаря этому числовое значение в этом поле будет наращиваться автоматически, аналог типа « Счётчик» в Access).
Предмет должен иметь тип nvarchar, это строковый тип данных (аналог string).
Рисунок 5. Структура таблицы « Расписание»
Шаг 4. Теперь, когда таблица « Расписание» создана необходимо обновить
установленную связь с БД. Когда мы подключали БД на шаге 2, у нас не было создано ни одной таблицы и на основании этой пустой базы данных была создана пустая схема xsd (dbDataSet.xsd). Автоматически эта схема не обновляется, поэтому придётся это сделать вручную. Для этого перейдите на закладку « Источники
данных» и |
кликните на иконку |
(« Настроить |
источник данных с помощью |
мастера»), |
рисунок 6. |
|
|
В появившемся окне раскройте раздел « Таблицы» |
и выделите галочкой таблицу |
||
« Расписание», нажмите Готово. |
|
|
|
Рисунок 6. Иконка « Настроить источник данных с помощью мастера»
Шаг 5. Теперь реализуем чтение\запись таблицы « Расписание» из формы. Для этого разместим на форме компонент DataGridView, он находится на « Панели Инструментов» в разделе « Данные». Так же разместите 2 кнопки, одна кнопка будет читать данные из БД, другая – записывать. На рисунке 7 показан примерный внешний вид формы с размещёнными компонентами.
Рисунок 7. Главная форма приложения.
После размещения компонентов выделите компонент DataGridView и кликните на маленькую кнопку со стрелкой в левом верхнем углу компонента (рисунок 8).
Рисунок 8. Кнопка окна быстрых настроек В появившемся окне выберите источник данных – таблицу « Расписание» ( Другие
источники данных –> Источники данных проекта –> dbDataSet –> Расписание).
Для кнопки « Прочитать данные» по событию Click добавьте код из листинга 1.
private void button1_Click(object sender, EventArgs e)
{
// Метод Fill читает данные из базы данны и заполяет указанную таблицу
расписаниеTableAdapter.Fill(dbDataSet.Расписание);
}
Листинг 1. Код кнопки « Прочитать данные».
Для кнопки « Записать данные» по событию Click добавьте код из листинга 2.
private void button2_Click(object sender, EventArgs e)
{
// Метод Update обновляет базу данных данными ИЗ указанной таблицы расписаниеTableAdapter.Update(dbDataSet.Расписание);
}
Листинг 2. Код кнопки « Записать данные».
Шаг 6.Запустите программу, нажав клавишу F5. Добавьте несколько новых записей,
после чего нажмите « Записать данные».
Шаг 7. На данном этапе у нас есть программа, которая отображает содержимое БД через элемент управления DataGridView. Однако в некоторых случаях необходимо манипулировать данными через код, а не оконный интерфейс.
Добавим функционал, который отображает расписание на сегодняшний день. Для начала нужно добавить новые компоненты на форму – тестовое поле (TextBox), в
котором будет отображаться расписание и 2 кнопки, по которым это расписание будет генерироваться (рисунок 9).
Рисунок 9. Расширенный интерфейс главного окна приложения Чтобы тестовое поле могло содержать несколько строк, необходимо установить для свойства Multiline значение true. Тестовое поле должно иметь имя txtInfo (будет
использоваться в коде). |
|
Шаг 8. Теперь напишем код для кнопки « Расписание на сегодня». |
Код для кнопки |
« Расписание на сегодня» приведён в листинге 3. |
|
Алгоритм работы следующий: |
|
1. Заполняем таблицу « Расписание» для виртуального |
набора данных |
dbDataSet (т.е. dbDataSet.Расписание) с помощью типизированного
TableAdapter-а (расписаниеTableAdapter). Вызываем метод Fill.
2.Перечисляем все строки в таблице dbDataSet.Расписание, удобнее всего это делать в цикле foreach
3.dbDataSet.РасписаниеRow представляет собой класс типизированной строки для таблицы Расписание. Т.о. экземпляр этого класса (row) содержит всю необходимую информацию (поля, методы) для манипуляции с одной строкой таблицы.
4.Затем проверяется, что день недели из текущей строки (row) равен текущему дню недели (из DateTime.Now). Здесь используется явное приведение к типу int, т.к. DateTime.Now.DayOfWeek имеет тип « перечисление DayOfWeek».
5.Затем с помощью метода Format класса string формируем строку в подходящем формате и выводим её в текстовое поле.
private void button3_Click(object sender, EventArgs e)
{
//Заполняем таблицу Расписание актуальными данными из БД расписаниеTableAdapter.Fill(dbDataSet.Расписание);
//Перечисляем все строки (row == строка, ряд) в таблице Расписание foreach (dbDataSet.РасписаниеRow row in dbDataSet.Расписание)
{
//если ДеньНедели из БД равен текущему дню денели...
if (row.ДеньНедели == (int)DateTime.Now.DayOfWeek)
{
//Формируем строку в заданном формате
//(Время_Пробел_Предмет_КонецСтроки) string strOut = string.Format("{0} {1}\r\n",
row.Время, row.Предмет);
// добавляем строку в текстовое поле txtInfo.AppendText(strOut);
}
}
}
Листинг 3. Код кнопки « Расписание на сегодня».
Шаг 9. Запустите программу, нажав клавишу F5. Обратите внимание, что вместе со временем выводится так же дата т.к. поле « Время» хранит не только время, но и дату. Чтобы отображалось только время, преобразуйте поле row.Время в строку с помощью метода ToString(“hh:mm”).
Текущая реализация отображения расписания работает однако имеет существенный недостаток – время отображается не в порядке возрастания, а в том порядке, в котором было занесено в БД. Т.е. если мы сначала занесён в БД занятие на 13:00, а потом (в этот же день) на 8:00. То они так и будут отображаться в таком порядке:
13:00 Математика
8:00 Экономика Чтобы исправить это, нужно отсортировать все отображаемые строки по полю
« Время». В листинге 4 приведён код, реализующий этот функционал.
private void button3_Click(object sender, EventArgs e)
{
//Заполняем таблицу Расписание актуальными данными из БД расписаниеTableAdapter.Fill(dbDataSet.Расписание);
//Временный список
List<dbDataSet.РасписаниеRow> aTimeTable = new
List<dbDataSet.РасписаниеRow>();
// Перечисляем все строки (row == строка, ряд) в таблице Расписание foreach (dbDataSet.РасписаниеRow row in dbDataSet.Расписание)
{
// если ДеньНедели из БД равен текущему дню денели...
if (row.ДеньНедели == (int)DateTime.Now.DayOfWeek)
{
// добавляем строку во временный список aTimeTable.Add(row);
}
}
//Сортируем (задаём функцию сравнения с 2 аргументами x и y)
//x и y имеют тип dbDataSet.РасписаниеRow
//функция сравнения должна возвращать число (int)
//1 если x > y, 0 если x == y и -1 если x < y
//чтобы не писать несколько условий вручную
//можно воспользоваться функцией CompareTo aTimeTable.Sort((x,y)=>x.Время.CompareTo(y.Время));
//Переносим из временного списка в тестовое поле foreach (dbDataSet.РасписаниеRow row in aTimeTable)
{
//Формируем строку в заданном формате
//(Время_Пробел_Предмет_КонецСтроки) string strOut = string.Format("{0} {1}\r\n",
row.Время.ToString("hh:mm"), row.Предмет);
// добавляем в тестовое поле txtInfo.AppendText(strOut);
}
}
Листинг 4. Код кнопки « Расписание на сегодня»( улуччшенный).
Шаг 10. Запустите программу, нажав клавишу F5. Убедитесь, что программа работает верно.
Шаг 11. Рассмотрим как реализовать тот же функционал отображения расписания,
используя лямбда-выражения вместо первого цикла foreach. Для этого будем использовать метод расширения Where, который выполняет фильтрацию на основании заданного условия. Добавьте для кнопки « Расписание на сегодня
(лямбда-выражения)» код из листинга 5.
private void button4_Click(object sender, EventArgs e)
{
// Заполняем таблицу Расписание актуальными данными из БД расписаниеTableAdapter.Fill(dbDataSet.Расписание);
//Where - выполняет фильтрацию на основании заданного условия
List<dbDataSet.РасписаниеRow> aTimeTable = dbDataSet.Расписание.Where((x) =>
x.ДеньНедели == (int) DateTime.Now.DayOfWeek).ToList();
// Сортировка
aTimeTable.Sort((x,y)=> x.Время.CompareTo(y.Время));
//Вывод
foreach (dbDataSet.РасписаниеRow row in aTimeTable)
{
//Формируем строку в заданном формате
//(Время_Пробел_Предмет_КонецСтроки) string strOut = string.Format("{0} {1}\r\n",
row.Время.ToString("hh:mm"), row.Предмет);
// добавляем в тестовое поле txtInfo.AppendText(strOut);
}
}
Листинг 5. Код кнопки « Расписание на сегодня(лямбда-выражения)».
Шаг 12. Запустите программу, нажав клавишу F5. Убедитесь, что программа
работает верно.
Самостоятельное задание 5.1.
Усовершенствовать учебное задание, добавив следующий функционал:
1.Программа должна выдавать расписание на следующий день
2.Программа должна отображать расписание внутри элемента управления
Label (чтобы нельзя было редактировать).
3.Если расписание на следующий день не заполнено, выводить расписание через день (или через два дня). Например, если сб. и вс. не учимся, то программа, запущенная в пятницу, должна выдавать расписание на понедельник.
Дополнительное задание (+2 балла к общему рейтингу).
Добавить отображение пустых пар (« окон»), пустые пары не должны заноситься
в БД. Пример:
Пустые пары не отображаются |
Пустые пары отображаются |
||
|
|
|
|
8:00 |
Математика |
8:00 |
Математика |
9:45 |
Социология |
9:45 |
Социология |
13:00 |
Английский |
11:30 |
- |
|
|
13:00 |
Английский |
|
|
|
|
