- •Java и c# технологии прикладного програмирования
- •Java и c# технологии прикладного програмирования
- •Содержание
- •Введение
- •Лабораторная работа № 1 Коллекции c#
- •Цель работы
- •Теоретические сведения
- •Общие сведения о платформе .Net
- •Общие сведения о коллекциях c#
- •Обобщенные коллекции с#
- •Порядок выполнения лабораторной работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Получение информации о типе
- •Экземпляр типа Type
- •Получение экземпляра типа Type
- •Динамическая загрузка сборок
- •Динамическая загрузка типов
- •Исследование типа
- •Характеристики типа как целого
- •Члены класса
- •Динамическое создание объекта и вызов методов
- •Создание объекта по его типу
- •Динамический вызов методов
- •Использование интерфейсов
- •Позднее связывание
- •Динамическое приведение типов
- •Новые механизмы абстракции
- •Динамическое создание типов
- •Динамическое создание программного кода
- •Динамическое создание класса
- •Динамическое создание перечислений
- •Динамический "Hello World!"
- •Динамическое разворачивание циклов
- •Атрибуты
- •Атрибут это класс
- •Декларативное программирование
- •Код, выполняемый во время разработки
- •Использование атрибутов
- •Использование встроенных атрибутов
- •Определение и использование пользовательских атрибутов
- •Пример декларативного программирования
- •Порядок выполнения работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Связный уровень взаимодействия ado.Net
- •Несвязный уровень взаимодействия ado.Net
- •Порядок выполнения работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Связи между объектами в FluentNHibernate
- •Связь один к одному
- •Связь один ко многим
- •Связь многие ко многим
- •Способы выборки объектов в FluentNHibernate
- •Запросы NativeSql
- •Запросы по критерию
- •Запросы по образцу
- •Запросы hql
- •Порядок выполнения работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Компиляция страниц по требованию
- •Страница asp.Net 2.0
- •Директива @Page
- •Жизненный цикл страницы
- •Новые свойства и методы объекта Page
- •Управление страницей
- •Установка выделения на элемент управления
- •Обновление данных без перезагрузки страницы
- •Отправка данных формы другой странице asp.Net
- •Шаблоны дизайна страниц
- •Создание шаблона дизайна
- •Создание страницы
- •Обработка шаблонов средой asp.Net
- •Использование разных шаблонов для разных браузеров
- •Порядок выполнения работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Библиотеки модульного тестирования в .Net
- •Unit Testing Framework от Microsoft
- •Порядок выполнения работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Контрольные вопросы
- •Рекомендованная литература
Порядок выполнения работы
В данном порядке выполнения лабораторной работы будет разработано приложение, которое будет работать с данными с базы данных (отображать, добавлять удалять, редактировать данные). Доступ к базе будет осуществляться с применением технологии ORM(objectrelationmapping)FluentNHibernate.В качестве СУБД был выбранPostgreSQL. Предметная область будет состоять из двух объектов: «Группа» и «Студент», которые состоят в отношении один ко многим. Старайтесь разобраться с кодом, который копируете в проект.
Этап I - Подготовка
Установите PostgreSQL. Создайте базу данныхuniversity.
Создайте новое приложение WindowsForms.
Создайте каталоги domain, mapping и dao.

Добавьте в каталог с проектом библиотеки для работы с СУБД PostgreSQL, библиотекиNHibernateи библиотекиFluentNHibernate. Данные библиотеки можно скачать по ссылкам:
|
Драйвер к postgreSQL |
http://www.postgresql.org/ |
|
Библиотеки NHibernate |
http://sourceforge.net/projects/nhibernate/ |
|
Библиотеки Fluent NHibernate |
http://fluentnhibernate.org/ |
В данном проекте были использованы архивы:
Npgsql2.0.10-bin-ms.net.zip
NHibernate-2.1.2.GA-bin.zip
fluentnhibernate-1.1.zip
Список всех необходимых библиотек приведен ниже:
-
Npgsql.dll
Mono.Security.dll
NHibernate.dll
Antlr3.Runtime.dll
Iesi.Collections.dll
log4net.dll
Castle.DynamicProxy2.dll
Castle.Core.dll
NHibernate.ByteCode.Castle.dll
FluentNHibernate.dll
Подключите библиотеки Npgsql.dll, NHibernate.dll, FluentNHibernate.dll и NHibernate.ByteCode.Castle к проекту (нажмите правой кнопкой на «Ссылки» в дереве объектов потом на «Добавить ссылку…», перейдите на закладку «Обзор», выберите необходимые файлы).

Теперь все готово для создания слоя доступа к данным DAO. В лабораторной работе можно использоватьNHibernateиFluentHibernateболее поздних версий, напримерNHibernate3.
Этап II – Создание слоя доступа к данным (DAO)
Будьте внимательны при разработке слоя доступа к данным, поскольку он будет использоваться в следующих лабораторных работах.
В каталоге domainсоздайте три класса-доменаEntityBase,Groupи Student. Тексты классов приведены ниже:
namespace lab4.domain
{
//Класс базовой сущности
public abstract class EntityBase
{
public virtual long Id { get; set; }
}
}
using System.Collections.Generic;
namespace lab4.domain
{
//Сущность группы
public class Group:EntityBase
{
private IList<Student> studentList = new List<Student>();
public virtual string GroupName { get; set; }
public virtual string CuratorName { get; set; }
public virtual string HeadmanName { get; set; }
public virtual IList<Student> StudentList
{
get { return studentList; }
set { studentList = value; }
}
}
}
namespace lab4.domain
{
//Сущность студента
public class Student:EntityBase
{
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual char Sex { get; set; }
public virtual int Year { get; set; }
public virtual Group Group { get; set; }
}
}
Создайте в каталоге daoинтерфейс IGenericDAO, в котором описаны все необходимые для слоя доступа к данным методы. Набор методов определяется на этапе проектирования в зависимости от потребностей системы. Интерфейс IGenericDAO приведен ниже:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace lab4.dao
{
public interface IGenericDAO<T>
{
void SaveOrUpdate(T item);
T GetById(long id);
List<T> GetAll();
void Delete(T item);
}
}
Помимо стандартного набора методов, daoкаждого объекта может иметь свой собственный дополнительный список методов. Так, например, для объекта-группы таким методом является getAllStudentOfGroup (получить список студентов заданной группы). Поэтому для каждого объекта предметной области необходимо создать свои интерфейсы, которые расширяют IGenericDAO. Ниже приведены интерфейсы IGroupDAO и IStudentDAO:
using lab4.domain;
using System.Collections.Generic;
namespace lab4.dao
{
public interface IGroupDAO:IGenericDAO<Group>
{
Group getGroupByName(string groupName);
IList<Student> getAllStudentOfGroup(string groupName);
void delGroupByName(string groupName);
}
}
using lab4.domain;
namespace lab4.dao
{
public interface IStudentDAO:IGenericDAO<Student>
{
Student getStudentByGroupFirstNameAndLastName(
string groupName, string firstName, string LastName);
}
}
Создайте в каталоге daoабстрактную фабрику, которая будет возвращатьDAOдля каждой сущности:
namespace lab4.dao
{
abstract public class DAOFactory
{
public abstract IStudentDAO getStudentDAO();
public abstract IGroupDAO getGroupDAO();
}
}
Теперь необходимо создать реализации интерфейсов IGenericDAO, IGroupDAO, IStudentDAO и абстрактной фабрики дляFluentNHibernate. Ниже приведена реализация IGenericDAO:
using System;
using System.Collections.Generic;
using NHibernate;
namespace lab4.dao
{
public class GenericDAO<T>:IGenericDAO<T>
{
protected ISession session;
public GenericDAO() { }
public GenericDAO(ISession session)
{
this.session = session;
}
public void SaveOrUpdate(T item)
{
ITransaction transaction = session.BeginTransaction();
session.SaveOrUpdate(item);
transaction.Commit();
}
public T GetById(long id)
{
return session.Get<T>(id);
}
public List<T> GetAll()
{
return new List<T>(session.CreateCriteria(typeof(T)).List<T>());
}
public void Delete(T item)
{
ITransaction transaction = session.BeginTransaction();
session.Delete(item);
transaction.Commit();
}
}
}
Создайте в каталоге daoреализацию интерфейсов IGroupDAO, IStudentDAO:
using lab4.domain;
using NHibernate;
using System.Collections.Generic;
using NHibernate.Criterion;
namespace lab4.dao
{
public class GroupDAO:GenericDAO<Group>, IGroupDAO
{
public GroupDAO(ISession session) : base(session) { }
public Group getGroupByName(string groupName)
{
Group group = new Group();
group.GroupName = groupName;
ICriteria criteria = session.CreateCriteria(typeof(Group))
.Add(Example.Create(group));
IList<Group> list = criteria.List<Group>();
group = list[0];
return group;
}
public IList<Student> getAllStudentOfGroup(string groupName)
{
var list = session.CreateSQLQuery(
"SELECT Students.* FROM Students JOIN Groups" +
" ON Students.GroupId = Groups.Id" +
" WHERE Groups.GroupName='" + groupName + "'")
.AddEntity("Student", typeof(Student))
.List<Student>();
return list;
}
public void delGroupByName(string groupName)
{
Group group = getGroupByName(groupName);
Delete(group);
}
}
}
using lab4.domain;
using NHibernate;
namespace lab4.dao
{
public class StudentDAO:GenericDAO<Student>, IStudentDAO
{
public StudentDAO(ISession session): base(session) { }
public Student getStudentByGroupFirstNameAndLastName(
string groupName, string firstName, string lastName)
{
var list = session.CreateSQLQuery(
"SELECT Students.* FROM Students JOIN Groups" +
" ON Students.GroupId = Groups.Id" +
" WHERE Groups.GroupName='" + groupName + "'" +
" and Students.FirstName='" + firstName + "'" +
" and Students.LastName='" + lastName + "'")
.AddEntity("Student", typeof(Student))
.List<Student>();
Student student = list[0];
return student;
}
}
}
Создайте реализацию абстрактной фабрики NHibernateDAOFactory:
using System;
using FluentNHibernate;
using NHibernate;
namespace lab4.dao
{
public class NHibernateDAOFactory:DAOFactory
{
/** NHibernate sessionFactory */
protected ISession session = null;
public NHibernateDAOFactory(ISession session)
{
this.session = session;
}
public override IStudentDAO getStudentDAO()
{
return new StudentDAO(session);
}
public override IGroupDAO getGroupDAO()
{
return new GroupDAO(session);
}
}
}
Создадим классы проецирования объектов предметной области на базу данных. В соответствии cmapping-классами в базе данных будут создаваться таблицы и связи между ними. При использованииNHibernateвместоFluentNHibernateвместо классов используются XML-файлы.Mapping-классы для объектов «Группа» и «Студент».
using FluentNHibernate.Mapping;
using lab4.domain;
namespace lab4.mapping
{
public class GroupMap:ClassMap<Group>
{
public GroupMap()
{
Table("Groups");
Id(x => x.Id).GeneratedBy.Native();
Map(x => x.GroupName);
Map(x => x.CuratorName);
Map(x => x.HeadmanName);
HasMany(x => x.StudentList)
.Inverse()
.Cascade.All()
.KeyColumn("GroupId");
}
}
}
using FluentNHibernate.Mapping;
using lab4.domain;
namespace lab4.mapping
{
public class StudentMap:ClassMap<Student>
{
public StudentMap()
{
Table("Students");
Id(x => x.Id).GeneratedBy.Native();
Map(x => x.FirstName);
Map(x => x.LastName);
Map(x => x.Sex);
Map(x => x.Year);
References(x => x.Group, "GroupId");
}
}
}
Слой доступа к данным реализован.
Этап III – Реализация слоя отображения
Слой отображения в данной лабораторной работе будет реализован с использованием WindowsForms(толстый клиент). В следующей лабораторной работе слой отображения будет реализован с использованием технологииASP.NETкак тонкий клиент.
Создайте три дополнительные формы. Одна будет использоваться для ввода настроек подключения, вторая - для добавления и изменения группы, третья – для добавления и изменения студента.
На главной форме разметите компонент MenuStrip, добавьте к нему пункт меню«Источник данных», а к пункту «Источник данных» пункты «Подключение к базе» и «Отключение от базы», создайте обработчики нажатия на эти два пункта меню.
Установите на форму компонент SplitConteinerдля того, чтобы разделить рабочую область формы на две части.
Установите с левую и правую части компонент GoupBox. Установите у левогоGoupBoxсвойствоTextв значение «Группы», а у правого свойствоTextв значение – «Студенты», установите у обоихGoupBoxсвойствоDockв значениеFill.
Разместите на левом и на правом GoupBoxкомпонентыDataGridView. Установите у них свойствоDockв значениеFill. ЛевыйDataGridViewбудет использоваться для отображения списка групп, а правый для отображения списка студентов в группе. Настройте каждый из DataGridView следующим образом: ReadOnly – True, MultiSelect – False, RowHeadersVisible – False, SelectionMode – FullRowSelect, AllowUserToAddRows - False.
Добавьте в первый DataGridViewколонки «Название группы», «ФИО куратора», «ФИО старосты», а во второй добавьте колонки «Имя», «Фамилия», «Пол», «Год рождения». Добавить колонки можно с помощью свойстваColumns. В конструкторе колонок необходимо внимательно следить за свойствомNameколонки, через которое потом происходит обращение к колонке из программы.
Добавьте два компонента ContextMenuStrip, свяжите одно контекстное меню с левымDataGridView, а другое с правымDataGridViewчерез свойствоContextMenuStrip. Добавьте в каждом меню три пункта «Добавить», «Удалить», «Заменить», к каждому пункту меню добавьте обработчик на нажатие.
Теперь необходимо реализовать функцию подключения приложения к базе данных. Связывать приложение с базой данных будет сессия NHibernate. Разместите на второй форме (Form2) пять компонентовTextBox, каждыйTextBoxможно подписать с использованием компонентаLabel. ПервыйTextBoxбудет использоваться для ввода имени хоста, второй – для ввода порта, третий – для ввода имени базы данных, четвертый – для ввода имени пользователя, а пятый – для ввода пароля. На форме также следует поместить кнопку и назвать ее, например, «Подключиться».
Конечный результат проектирования формы подключения к базе представлен на рисунке 4.1.

Рисунок 4.1 – Форма подключения к базе
Каждая форма должна иметь доступ к родительской форме (Form1), а также к сессии (ISession). Откройте формуForm2 с использованием редактораCSharp. Добавьте над конструктором формы поля:
private ISessionFactory factory;
//Ссылка на сессию
private ISession session;
//Ссылка на родительскую форму
private Form1 perent;
Добавьте метод по установке поля perent:
public void setPerent(Form1 perent)
{
this.perent = perent;
}
Добавьте методы по открытию сессии:
//Методоткрытиясессии
private ISession openSession(String host, int port, String database,
String user, String passwd)
{
ISession session = null;
//Получениессылкинатекущуюсборку
Assembly mappingsAssemly = Assembly.GetExecutingAssembly();
if (factory == null)
{
//Конфигурирование фабрики сессий
factory = Fluently.Configure()
.Database(PostgreSQLConfiguration
.PostgreSQL82.ConnectionString(c => c
.Host(host)
.Port(5432)
.Database(database)
.Username(user)
.Password(passwd)))
.Mappings(m => m.FluentMappings
.AddFromAssembly(mappingsAssemly))
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
}
//Открытиесессии
session = factory.OpenSession();
return session;
}
//Метод для автоматического создания таблиц в базе данных
private static void BuildSchema(Configuration config)
{
new SchemaExport(config).Create(false, true);
}
Добавьте обработчик нажатия на кнопку «Подключиться»:
private void button1_Click(object sender, EventArgs e)
{
session = openSession(this.textBox1.Text,
Convert.ToInt32(this.textBox2.Text),
this.textBox3.Text, this.textBox4.Text, this.textBox5.Text);
//Скрытие формы
this.Visible = false;
//Передача открытой сессии открытой форме
perent.setSession(session);
//Вывод в таблицу всех групп
perent.fillDataGridView1();
}
Теперь необходимо добавить функции по подключению и отключении приложения от базы данных. Откройте Form1в режиме редактораCSharp. Добавьте над конструктором формы поля:
private ISession session;
private Form2 form2 = null;
private Form3 form3 = null;
private Form4 form4 = null;
Поля form3, иform4 понадобятся для форм добавления и редактирования групп и студентов.
Также необходимо добавить метод setSession(), чтобы установки соединения могла передасть сессию главной форме:
public void setSession(ISession session)
{
this.session = session;
}
Для удобства обращения к форме добавьте метод по созданию и инициализации формы:
private Form2 getForm2()
{
if (form2 == null)
{
form2 = new Form2();
}
form2.setPerent(this);
return form2;
}
Заполните обработчики нажатия на пункты меню «Подключение к базе», «Отключиться от базы»:
private void присоединитьсяКБазеToolStripMenuItem_Click(
object sender, EventArgs e)
{
getForm2().Visible = true;
}
private void отключитьсяОтБазыToolStripMenuItem_Click(
object sender, EventArgs e)
{
session.Close();
dataGridView1.Rows.Clear();
dataGridView2.Rows.Clear();
}
Добавьте методы по заполнению компонентов DataGridViewданными о группах и студентах:
//Метод по заполнению dataGridView1
public void fillDataGridView1()
{
dataGridView1.Rows.Clear();
//Создание экземпляра фабрики NHibernate
DAOFactory dao = new NHibernateDAOFactory(session);
//Получение dao группы
IGroupDAO groupDAO = dao.getGroupDAO();
//Получение коллекции групп с базы
List<Group> groupList = groupDAO.GetAll();
//Вывод всех групп в таблицу
foreach (Group g in groupList)
{
DataGridViewRow row = new DataGridViewRow();
DataGridViewTextBoxCell cell1 = new DataGridViewTextBoxCell();
DataGridViewTextBoxCell cell2 = new DataGridViewTextBoxCell();
DataGridViewTextBoxCell cell3 = new DataGridViewTextBoxCell();
cell1.ValueType = typeof(string);
cell1.Value = g.GroupName;
cell2.ValueType = typeof(string);
cell2.Value = g.CuratorName;
cell3.ValueType = typeof(string);
cell3.Value = g.HeadmanName;
row.Cells.Add(cell1);
row.Cells.Add(cell2);
row.Cells.Add(cell3);
dataGridView1.Rows.Add(row);
}
}
//Вывод всех студентов заданной группы в dataGridView2
public void fillDataGridView2(string key)
{
dataGridView2.Rows.Clear();
//Создание фабрики NHibernate
DAOFactory dao = new NHibernateDAOFactory(session);
//Получение dao группы
IGroupDAO groupDAO = dao.getGroupDAO();
//Получение студентов заданной группы
IList<Student> studentList = groupDAO.getAllStudentOfGroup(key);
foreach (Student s in studentList)
{
DataGridViewRow row = new DataGridViewRow();
DataGridViewTextBoxCell cell1 = new DataGridViewTextBoxCell();
DataGridViewTextBoxCell cell2 = new DataGridViewTextBoxCell();
DataGridViewTextBoxCell cell3 = new DataGridViewTextBoxCell();
DataGridViewTextBoxCell cell4 = new DataGridViewTextBoxCell();
cell1.ValueType = typeof(string);
cell1.Value = s.FirstName;
System.Console.WriteLine(s.FirstName + "\n");
cell2.ValueType = typeof(string);
cell2.Value = s.LastName;
cell3.ValueType = typeof(string);
cell3.Value = s.Sex;
cell4.ValueType = typeof(string);
cell4.Value = s.Year;
row.Cells.Add(cell1);
row.Cells.Add(cell2);
row.Cells.Add(cell3);
row.Cells.Add(cell4);
dataGridView2.Rows.Add(row);
}
}
Приступим к реализации функций добавления, удаления и замены группы. Откройте Form3в режиме конструктора, добавьте три компонентаTextBox (поле ввода). Первое поле ввода будет использоваться для ввода названия группы, второе – для ввода ФИО куратора, третье – для ввода ФИО старосты. Поля ввода можно подписать компонентомLabel. Добавьте две кнопки: «Добавить» и «Заменить». Результат проектирования формы группы представлен на рисунке 4.2.

Рисунок 4.2 – Форма добавления и замены группы
Откройте Form3в режиме конструктораCSharp. Добавьте над конструктором класса поля:
private ISession session;
private Form1 perent;
private string key;
Первое поле хранит в себе ссылку на сессию, второе поле – ссылку на главную форму, а третье – ключ, который нам необходим будет при замене группы. Для установки значений этих полей добавьте методы:
public void setPerent(Form1 perent)
{
this.perent = perent;
}
public void setSession(ISession session)
{
this.session = session;
}
public void setKey(string key)
{
this.key = key;
}
Для того чтобы получить доступ к полям ввода и кнопкам с главной формы добавьте следующие set-методы:
public void setTextBox1Text(string text)
{
this.textBox1.Text = text;
}
public void setTextBox2Text(string text)
{
this.textBox2.Text = text;
}
public void setTextBox3Text(string text)
{
this.textBox3.Text = text;
}
public void setButton1Visible(bool visible)
{
this.button1.Visible = visible;
}
public void setButton2Visible(bool visible)
{
this.button2.Visible = visible;
}
Добавьте обработчики нажатия кнопок «Добавить» и «Заменить»:
//Обработчик на Добавить
private void button1_Click(object sender, EventArgs e)
{
DAOFactory dao = new NHibernateDAOFactory(session);
IGroupDAO groupDAO = dao.getGroupDAO();
Group group = new Group();
group.GroupName = textBox1.Text;
group.HeadmanName = textBox2.Text;
group.CuratorName = textBox3.Text;
groupDAO.SaveOrUpdate(group);
perent.fillDataGridView1();
this.Visible = false;
}
//Обработчик на Заменить
private void button2_Click(object sender, EventArgs e)
{
DAOFactory dao = new NHibernateDAOFactory(session);
IGroupDAO groupDAO = dao.getGroupDAO();
Group group = groupDAO.getGroupByName(key);
group.GroupName = textBox1.Text;
group.CuratorName = textBox2.Text;
group.HeadmanName = textBox3.Text;
groupDAO.SaveOrUpdate(group);
this.Visible = false;
perent.fillDataGridView1();
}
Откройте Form1в редакторе кодаCSharp.Для удобства работы сForm3 добавьте метод:
private Form3 getForm3()
{
if (form3 == null)
{
form3 = new Form3();
}
form3.setSession(session);
form3.setPerent(this);
return form3;
}
Заполните обработчики «Добавить», «Удалить», «Заменить» для контекстного меню группы:
//Нажатие на "Добавить" в контекстном меню группы
private void добавитьToolStripMenuItem_Click(object sender, EventArgs e)
{
getForm3().Visible = true;
getForm3().setTextBox1Text("");
getForm3().setTextBox2Text("");
getForm3().setTextBox3Text("");
getForm3().setButton1Visible(true);
getForm3().setButton2Visible(false);
}
//Нажатие на "Удалить" в контекстном меню группы
private void удалитьToolStripMenuItem_Click(object sender, EventArgs e)
{
DAOFactory dao = new NHibernateDAOFactory(session);
IGroupDAO groupDAO = dao.getGroupDAO();
int selectedRow = dataGridView1.SelectedCells[0].RowIndex;
string key = (string)dataGridView1.Rows[selectedRow].Cells[0].Value;
DialogResult dr = MessageBox.Show("Удалить студента?", "",
MessageBoxButtons.YesNo);
if (dr == DialogResult.Yes)
{
try
{
groupDAO.delGroupByName(key);
this.fillDataGridView1();
}
catch (Exception)
{
}
}
}
//Нажатие на "Заменить" в контекстном меню группы
private void изменитьToolStripMenuItem_Click(object sender, EventArgs e)
{
int selectedRow = dataGridView1.SelectedCells[0].RowIndex;
string key = (string)dataGridView1.Rows[selectedRow].Cells[0].Value;
DAOFactory dao = new NHibernateDAOFactory(session);
IGroupDAO groupDAO = dao.getGroupDAO();
Group group = groupDAO.getGroupByName(key);
getForm3().Visible = true;
getForm3().setKey(key);
getForm3().setTextBox1Text(group.GroupName);
getForm3().setTextBox2Text(group.CuratorName);
getForm3().setTextBox3Text(group.HeadmanName);
getForm3().setButton1Visible(false);
getForm3().setButton2Visible(true);
}
Для того чтобы при нажатии на строчку DataGridViewдля группы вDataGridViewдля студентов отображался список студентов выделенной группы, добавьте обработчик нажатия на строчкуDataGridView:
//Обработчик нажатия на строчку DataGridView группы
private void dataGridView1_CellClick(
object sender, DataGridViewCellEventArgs e)
{
int selectedRow = dataGridView1.SelectedCells[0].RowIndex;
string key = (string)dataGridView1.Rows[selectedRow].Cells[0].Value;
fillDataGridView2(key);
}
Приступим к реализации функций добавления, удаления и замены студента. Откройте Form4в режиме конструктора. Добавьте 4 компонентаTextBox(поля ввода). Первое поле будет использоваться для ввода имени студента, второе – для ввода фамилии студента, третье – для ввода пола студента, четвертое – для ввода года рождения студента. Каждое поле ввода целесообразно подписать с использованием компонентаLabel. Добавьте на форму кнопки «Добавить» и «Заменить». Результат проектирования формы студента представлен на рисунке 4.3

Рисунок 4.3 – Форма добавления и замены студента
Откройте Form4 в режиме редактораCSharp. Добавьте над конструктором класса формы поля:
private ISession session;
private Form1 perent;
private string key1;
private string key2;
private string key3;
Поле key1 содержит название группы, поле key2 содержит имя студента, поле key3 содержит фамилию студента.
Добавьте set-методы по установке вышеописанных переменных:
public void setSession(ISession session)
{
this.session = session;
}
public void setPerent(Form1 perent)
{
this.perent = perent;
}
public void setKey1(string key1)
{
this.key1 = key1;
}
public void setKey2(string key2)
{
this.key2 = key2;
}
public void setKey3(string key3)
{
this.key3 = key3;
}
Для доступа к полям ввода и кнопкам формы добавьте следующие set-методы:
public void setTextBox1Text(string text)
{
this.textBox1.Text = text;
}
public void setTextBox2Text(string text)
{
this.textBox2.Text = text;
}
public void setTextBox3Text(string text)
{
this.textBox3.Text = text;
}
public void setTextBox4Text(string text)
{
this.textBox4.Text = text;
}
public void setButton1Visible(bool visible)
{
this.button1.Visible = visible;
}
public void setButton2Visible(bool visible)
{
this.button2.Visible = visible;
}
Создайте обработчики нажатия на кнопки «Добавить» и «Заменить»:
//Обработчик нажатия на "Добавить"
private void button1_Click(object sender, EventArgs e)
{
DAOFactory dao = new NHibernateDAOFactory(session);
IGroupDAO groupDAO = dao.getGroupDAO();
Group group = groupDAO.getGroupByName(key1);
Student student = new Student();
student.FirstName = textBox1.Text;
student.LastName = textBox2.Text;
student.Sex = textBox3.Text[0];
student.Year = Int32.Parse(textBox4.Text);
group.StudentList.Add(student);
student.Group = group;
groupDAO.SaveOrUpdate(group);
perent.fillDataGridView2(key1);
this.Visible = false;
}
//Обработчик нажатия на "Заменить"
private void button2_Click(object sender, EventArgs e)
{
DAOFactory dao = new NHibernateDAOFactory(session);
IStudentDAO studentDAO = dao.getStudentDAO();
Student student = studentDAO
.getStudentByGroupFirstNameAndLastName(key1, key2, key3);
student.FirstName = textBox1.Text;
student.LastName = textBox2.Text;
student.Sex = textBox3.Text[0];
student.Year = Int32.Parse(textBox4.Text);
studentDAO.SaveOrUpdate(student);
this.Visible = false;
perent.fillDataGridView2(key1);
}
Откройте Form1 с помощью редактораCSharp.Для удобства работы сForm4 добавьте метод:
private Form4 getForm4()
{
if (form4 == null)
{
form4 = new Form4();
}
form4.setSession(session);
form4.setPerent(this);
return form4;
}
Заполните обработчики нажатия на «Добавить», «Удалить», «Заменить» контекстного меню студента:
//Нажатие на "Добавить" в контекстном меню студента
private void добавитьToolStripMenuItem1_Click(object sender, EventArgs e)
{
int selectedRow = dataGridView1.SelectedCells[0].RowIndex;
string key = (string)dataGridView1.Rows[selectedRow].Cells[0].Value;
getForm4().Visible = true;
getForm4().setButton1Visible(true);
getForm4().setButton2Visible(false);
getForm4().setTextBox1Text("");
getForm4().setTextBox2Text("");
getForm4().setTextBox3Text("");
getForm4().setTextBox4Text("");
getForm4().setKey1(key);
}
//Нажатие на "Удалить" в контекстном меню студента
private void удалитьToolStripMenuItem1_Click(object sender, EventArgs e)
{
int selectedRow = dataGridView1.SelectedCells[0].RowIndex;
string key1 = (string)dataGridView1.Rows[selectedRow].Cells[0].Value;
selectedRow = dataGridView2.SelectedCells[0].RowIndex;
string key2 = (string)dataGridView2.Rows[selectedRow].Cells[0].Value;
selectedRow = dataGridView2.SelectedCells[0].RowIndex;
string key3 = (string)dataGridView2.Rows[selectedRow].Cells[1].Value;
DAOFactory dao = new NHibernateDAOFactory(session);
IStudentDAO studentDAO = dao.getStudentDAO();
Student student = studentDAO
.getStudentByGroupFirstNameAndLastName(key1, key2, key3);
student.Group.StudentList.Remove(student);
studentDAO.Delete(student);
fillDataGridView2(key1);
}
//Нажатие на "Заменить" в контекстном меню студента
private void изменитьToolStripMenuItem1_Click(object sender, EventArgs e)
{
int selectedRow = dataGridView1.SelectedCells[0].RowIndex;
string key1 = (string)dataGridView1.Rows[selectedRow].Cells[0].Value;
selectedRow = dataGridView2.SelectedCells[0].RowIndex;
string key2 = (string)dataGridView2.Rows[selectedRow].Cells[0].Value;
selectedRow = dataGridView2.SelectedCells[0].RowIndex;
string key3 = (string)dataGridView2.Rows[selectedRow].Cells[1].Value;
DAOFactory dao = new NHibernateDAOFactory(session);
IStudentDAO studentDAO = dao.getStudentDAO();
Student student = studentDAO
.getStudentByGroupFirstNameAndLastName(key1, key2, key3);
getForm4().Visible = true;
getForm4().setTextBox1Text(student.FirstName);
getForm4().setTextBox2Text(student.LastName);
getForm4().setTextBox3Text(student.Sex.ToString());
getForm4().setTextBox4Text(student.Year.ToString());
getForm4().setKey1(key1);
getForm4().setKey2(key2);
getForm4().setKey3(key3);
getForm4().setButton1Visible(false);
getForm4().setButton2Visible(true);
}
Добавьте обработчик на изменение размеров формы:
private void Form1_Resize(object sender, EventArgs e)
{
this.dataGridView1.Columns["Column1"].Width =
(this.dataGridView1.Width / 3) - 1;
this.dataGridView1.Columns["Column2"].Width =
(this.dataGridView1.Width / 3) - 1;
this.dataGridView1.Columns["Column3"].Width =
(this.dataGridView1.Width / 3) - 1;
this.dataGridView2.Columns["Column4"].Width =
System.Convert.ToInt32(this.dataGridView2.Width * 0.3) - 1;
this.dataGridView2.Columns["Column5"].Width =
System.Convert.ToInt32(this.dataGridView2.Width * 0.3) - 1;
this.dataGridView2.Columns["Column6"].Width =
System.Convert.ToInt32(this.dataGridView2.Width * 0.1) - 1;
this.dataGridView2.Columns["Column7"].Width =
System.Convert.ToInt32(this.dataGridView2.Width * 0.3) - 1;
}
Результат работы приложения представлен на рисунке 4.4.

Рисунок 4.4 – Результат работы приложения
