Лекции / Глава 17. Entity Framework
.pdfДля этих классов контекст данных будет создавать следующую таблицу
UserProfiles:
Листинг 17.26
1 |
CREATE TABLE [dbo].[UserProfiles] ( |
||
2 |
[Id] |
INT |
NOT NULL, |
3 |
[Name] |
NVARCHAR (MAX) NULL, |
|
4 |
[NumberGroup] |
INT |
NOT NULL, |
5 |
[PersonalDate] NVARCHAR (MAX) NULL, |
||
6 |
CONSTRAINT [PK_dbo.UserProfiles] PRIMARY KEY CLUSTERED ([Id] |
||
ASC), |
|
|
|
7 |
CONSTRAINT [FK_dbo.UserProfiles_dbo.Users_Id] FOREIGN KEY |
||
([Id]) REFERENCES [dbo].[Users] ([Id]) |
|||
8 |
); |
|
|
Посмотрим, как работать с моделями с такой связью. Рассмотрим сценарий регистрации пользователей в информационную систему.
Создадим форму для регистрации пользователей:
Рисунок 37
41
Реализация метода обработчика события нажатия на кнопку «Зарегистрироваться»:
|
|
Листинг 17.27 |
|
|
|
|
|
|
if (textBoxUserLogin.Text != "" |
|
|
|
&& textBoxUserPassword.Text != "" |
|
|
|
&& textBoxUserProfileName.Text != "" |
С помощью составного условия проверяется |
|
1 |
&& textBoxUserProfileNumberGroup.Text != "" |
заполненность всех полей. |
|
|
|||
|
&& textBoxUserProfilePersonalDate.Text != "" |
|
|
|
&& comboBoxUserRole.Text != "") |
|
|
|
|
|
|
2 |
{ |
|
|
|
|
||
|
|
|
|
3 |
using (UserContext db = new UserContext()) |
Подключение контекста данных UserContext |
|
|
|
||
|
|
|
|
4 |
{ |
|
|
|
|
||
|
|
|
|
|
User user = new User { Login = |
Создание объекта user класса User и |
|
|
textBoxUserLogin.Text, Password = |
||
|
инициализация его свойств данными, |
||
5 |
textBoxUserPassword.Text, Role = |
||
|
|||
|
введенными через соответствующие textBox |
||
|
comboBoxUserRole.Text }; |
||
|
|
||
|
|
|
|
|
db.Users.Add(user); |
Добавление созданного объекта user в |
|
6 |
коллекцию сущностей Users из контекста |
||
|
|||
|
|
||
|
|
|
42
|
|
данных, отвечающую за хранение сущностей в |
|
|
|
базе данных |
|
|
|
|
|
|
db.SaveChanges(); |
Сохранение изменений результата запроса в базе |
|
7 |
данных |
||
|
|||
|
|
||
|
|
|
|
|
if (comboBoxUserRole.Text == "Студент") |
Если выбранное значение в раскрывающемся |
|
8 |
списке comboBox это "Студент" |
||
|
|||
|
|
||
|
|
|
|
9 |
{ |
|
|
|
|
||
|
|
|
|
|
UserProfile userProfile = new UserProfile { Id = |
|
|
|
user.Id, Name = textBoxUserProfileName.Text, |
Создание объекта userProfile класса |
|
|
NumberGroup = |
UserProfile и инициализация его свойств |
|
10 |
int.Parse(textBoxUserProfileNumberGroup.Text), |
данными, введенными через соответствующие |
|
|
PersonalDate = textBoxUserProfilePersonalDate.Text |
textBox |
|
|
}; |
|
|
|
|
|
|
|
|
Добавление созданного объекта userProfile в |
|
|
db.UserProfiles.Add(userProfile); |
коллекцию сущностей UserProfiles из |
|
11 |
контекста данных, отвечающую за хранение |
||
|
|
||
|
|
сущностей в базе данных |
|
|
|
|
43
|
db.SaveChanges(); |
Сохранение изменений результата запроса в базе |
|
12 |
данных |
||
|
|
||
|
|
|
|
13 |
} |
|
|
|
|
|
|
|
else if (comboBoxUserRole.Text == "Преподаватель") |
Если выбранное значение в раскрывающемся |
|
14 |
списке comboBox это "Преподаватель" |
||
|
|
||
|
|
|
|
15 |
{ |
|
|
|
|
|
|
|
UserProfile userProfile = new UserProfile { Id = |
Создание объекта userProfile класса |
|
|
UserProfile и инициализация его свойств |
||
|
user.Id, Name = textBoxUserProfileName.Text, |
||
|
данными, введенными через соответствующие |
||
16 |
NumberGroup = 0, PersonalDate = |
||
textbox (для преподавателя номер группы будет |
|||
|
textBoxUserProfilePersonalDate.Text }; |
||
|
по умолчанию равен 0) |
||
|
|
||
|
|
|
|
|
|
Добавление созданного объекта userProfile в |
|
|
db.UserProfiles.Add(userProfile); |
коллекцию сущностей UserProfiles из |
|
17 |
контекста данных, отвечающую за хранение |
||
|
|
||
|
|
сущностей в базе данных |
|
|
|
|
|
|
db.SaveChanges(); |
Сохранение изменений результата запроса в базе |
|
18 |
данных |
||
|
|
||
|
|
|
44
|
|
Создание объекта professor класса Professor |
|
Professor professor = new Professor { Id = |
и инициализация его свойств данными, |
|
userProfile.Id, Name = |
введенными через соответствующие textbox |
19 |
textBoxUserProfileName.Text, PersonalData = |
(при регистрации преподавателя создается |
|
textBoxUserProfilePersonalDate.Text, Position = |
последовательно две сущности – для хранения |
|
textBoxUserProfileNumberGroup.Text }; |
профиля преподавателя как пользователя |
|
|
системы и дипломного руководителя) |
|
|
|
|
|
Добавление созданного объекта professor в |
|
db.Professors.Add(professor); |
коллекцию сущностей Professors из контекста |
20 |
данных, отвечающую за хранение сущностей в |
|
|
|
|
|
|
базе данных |
|
|
|
|
db.SaveChanges(); |
Сохранение изменений результата запроса в базе |
21 |
данных |
|
|
|
|
|
|
|
22 |
} |
|
|
|
|
23 |
} |
|
|
|
|
|
this.MainForm.Visible = true; |
Переход в форму авторизации после успешной |
24 |
регистрации |
|
|
|
|
|
|
|
25 |
this.Visible = false; |
Скрытие формы регистрации |
|
|
|
26 |
} |
|
|
|
|
|
45 |
|
Обратите внимание, что при создании двух объектов, связанных между собой отношением один ко многим,
необходимо инициализировать атрибут Id подчиненного объекта (в нашей случае подчиненным является userProfile
в паре user-userProfile и professor в паре userProfile-professor) значением атрибута Id родительского объекта. Например, в строке 10 и 16 при создании объекта userProfile свойству Id было присвоено значение user.Id,
то есть Id родительского объекта user, который был предварительно создан.
Рассмотрим пример редактирования данных. Добавим возможность редактирования логина, пароля и информации
«О себе» после входа в личную страницу пользователя в информационной системе. Создадим следующую форму для редактирования данных учетной записи пользователя:
Рисунок 38
Реализация метода обработчика события нажатия на кнопку подтверждения изменений « »:
46
|
|
Листинг 17.28 |
|
|
|
|
|
Создание объекта SelectedUser для хранения |
1 |
User SelectedUser = null; |
пользователя, у которого надо изменить значения |
|
|
атрибутов |
|
|
|
2 |
using (UserContext db = new UserContext()) |
Подключение контекста данных UserContext |
|
||
|
|
|
3 |
{ |
|
|
|
|
|
|
Цикл для обработки элементов коллекции |
4 |
foreach (User user in db.Users) |
db.Users (коллекция сущностей Users из базы |
|
||
|
|
данных) |
|
|
|
5 |
{ |
|
|
|
|
|
|
Проверка на совпадение логина пользователя |
|
|
this.User, для которого выбрана опция |
6 |
if(user.Login == this.User.Login) |
изменения данных, с логином каждого |
|
|
|
|
|
пользователя из базы данных |
|
|
|
7 |
{ |
|
|
|
|
|
|
При совпадении логина – присваиваем |
8 |
SelectedUser = user; |
переменной SelectedUser ссылку на объект |
|
||
|
|
user (найденный элемент из базы данных) |
|
|
|
47
9 |
} |
|
|
|
|
10 |
} |
|
|
|
|
11 |
SelectedUser.Login = textBoxLogin.Text; |
Изменение логина у найденного пользователя |
|
||
|
|
|
12 |
SelectedUser.Password = textBoxPassword.Text; |
Изменение пароля у найденного пользователя |
|
||
|
|
|
|
SelectedUser.Profile.PersonalDate = |
Изменение данных «О себе» у найденного |
13 |
|
|
textBoxPersonalData.Text; |
пользователя |
|
|
|
|
|
|
Сохранение изменений результата запроса в базе |
14 |
db.SaveChanges(); |
данных |
|
|
|
|
|
|
15 |
} |
|
|
|
|
|
MessageBox.Show("Изменения сохранены", |
Вывод сообщения об успешности завершения |
16 |
|
|
"Сообщение"); |
операции |
|
|
|
|
17 |
this.Visible = false; |
Скрытие текущей формы |
|
||
|
|
|
|
|
Открытие формы просмотра учетной записи |
18 |
FormStudentAccount.Visible = true; |
студента |
|
|
|
|
|
|
При удалении надо учитывать следующее: так как объект UserProfile требует наличие объекта User и зависит от этого объекта, то при удалении связанного объекта User надо будет удалить и связанный с ним объект UserProfile,
поскольку по умолчанию у нас не предусмотрено каскадное удаление при данной связи. Если же будет удален объект
UserProfile, на объект User это никак не повлияет:
48
|
|
Листинг 17.29 |
|
|
|
1 |
using(UserContext db = new UserContext()) |
Подключение контекста данных UserContext |
|
|
|
2 |
{ |
|
|
|
|
|
|
Цикл для обработки элементов коллекции |
|
|
db.Users (коллекция сущностей Users из базы |
3 |
foreach(User user in db.Users.ToList()) |
данных). Здесь коллекция db.Users |
|
|
преобразуется из DbSet в коллекцию List с |
|
|
помощью метода ToList(). |
|
|
|
4 |
{ |
|
|
|
|
|
|
Проверка на совпадение Id пользователя со |
|
|
значением, выбранным в списке listBoxUsers. |
5 |
if (user.Id == (string)listBoxUsers.SelectedItem) |
Так как свойство SelectedItem возвращает |
|
|
значение в типе данных object, необходимо |
|
|
преобразование в строковый тип (string). |
|
|
|
6 |
{ |
|
|
|
|
|
|
Проверка на ненулевое значение атрибута |
7 |
if (user.Profile != null) |
UserProfile у сущности User (наличие у |
|
|
пользователя профиля с личными данными) |
|
|
|
|
49 |
|
8 |
{ |
|
|
|
|
|
|
|
|
Если профиль существует, то происходит |
|
|
|
удаление профиля с помощью метода Remove. |
|
9 |
db.UserProfiles.Remove(user.Profile); |
Метод Remove применяется по отношению к |
|
коллекции UserProfiles из контекста данных и |
|||
|
|
||
|
|
в качестве параметра в него передается ссылка на |
|
|
|
удаляемый объект user.Profile. |
|
|
|
|
|
10 |
} |
|
|
|
|
|
|
|
|
Удаление пользователя с помощью метода |
|
|
|
Remove, который применяется по отношению к |
|
11 |
db.Users.Remove(user); |
коллекции Users из контекста данных и в |
|
|
|
качестве параметра в него передается ссылка на |
|
|
|
удаляемый объект user |
|
|
|
|
|
12 |
db.SaveChanges();}}} |
Сохранение изменений результата запроса в базе |
|
данных |
|||
|
|
||
|
|
|
50