Добавил:
Преподаватель Колледжа информационных технологий Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекции / Глава 17.2 Entity Framework 2

.pdf
Скачиваний:
46
Добавлен:
08.05.2022
Размер:
1.04 Mб
Скачать

Листинг 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 (найденный элемент из базы данных)

 

 

 

21

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 это никак не повлияет:

22

 

 

Листинг 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 (наличие у

 

 

пользователя профиля с личными данными)

 

 

 

 

23

 

8

{

 

 

 

 

 

 

Если профиль существует, то происходит

 

 

удаление профиля с помощью метода Remove.

9

db.UserProfiles.Remove(user.Profile);

Метод Remove применяется по отношению к

коллекции UserProfiles из контекста данных и

 

 

 

 

в качестве параметра в него передается ссылка на

 

 

удаляемый объект user.Profile.

 

 

 

10

}

 

 

 

 

 

 

Удаление пользователя с помощью метода

 

 

Remove, который применяется по отношению к

11

db.Users.Remove(user);

коллекции Users из контекста данных и в

 

 

качестве параметра в него передается ссылка на

 

 

удаляемый объект user

 

 

 

12

db.SaveChanges();}}}

Сохранение изменений результата запроса в базе

данных

 

 

 

 

 

24

§17.10 Связь один ко многим

Связь один-ко-многим реализуется, если одна модель хранит ссылку на один объект другой модели, а вторая модель может ссылаться на коллекцию объектов первой модели. Например, у одного дипломного руководителя может существовать несколько тем для дипломных проектов, которые он может предложить студентам:

Листинг 17.30

1

public class Professor

2

{

3

[Key, ForeignKey("UserProfile")]

4

public int Id { get; set; }

5

public string Name { get; set; }

6

public string Position { get; set; }

7

public string PersonalData { get; set; }

8

public virtual UserProfile UserProfile { get; set; }

9

public virtual ICollection<Thesis> Theses { get; set;

}

 

10

public Professor()

11

{

12

this.Theses = new List<Thesis>();

13

}

14

}

 

 

15

public class Thesis

16

{

17

public int Id { get; set; }

18

public string Name { get; set; }

19

public int? ProfessorId { get; set; }

20

public virtual Professor Professor { get; set; }

21

}

 

 

Обычное свойство ProfessorId и навигационное свойство Professor

будет представлять собой внешний ключ подчиненной сущности Thesis.

Таким же образом в классе Team создается навигационное свойство Players,

представляющее собой интерфейс обобщенной коллекции

ICollection<Thesis>, через которое мы можем получать предлагаемые темы дипломных работ определенного преподавателя.

25

Рассмотрим реализацию метода добавления предлагаемых тем в коллекцию дипломного руководителя. Создадим следующую форму для добавления и просмотра тем:

Рисунок 7

26

Реализация метода обработчика события нажатия на кнопку «Добавить»:

 

 

 

Листинг 17.31

 

 

 

 

1

Thesis thesis = null;

 

Создание объекта класса Thesis

 

 

 

 

 

 

 

2

using (UserContext db = new UserContext())

 

Подключение контекста данных UserContext

 

 

 

 

 

 

 

3

{

 

 

 

 

 

 

 

 

 

 

 

 

Цикл для обработки элементов коллекции

 

 

 

db.Professors (коллекция сущностей

 

 

 

Professors из базы данных).

 

foreach (Professor professor in

 

Метод Include применяется для упреждающей

 

 

загрузки - это процесс, при котором запрос для

4

db.Professors.Include("Theses"))

 

 

 

 

 

одного типа сущности также загружает связанные

 

 

 

 

 

 

сущности в составе запроса (в данном случае

 

 

 

совместно с Professor загружается связанная

 

 

 

сущность Theses).

 

 

 

 

5

{

 

 

 

 

 

 

 

 

 

 

 

 

Проверка на совпадение имени дипломного

 

if (this.Professor.Name == professor.Name)

 

руководителя, для которого применяется

6

 

добавление новой темы, с именем каждого

 

 

 

 

 

 

 

 

дипломного руководителя из базы данных.

 

 

 

 

 

 

27

 

7

{

 

 

 

 

Если дипломный руководитель найден в базе

 

данных, то вызывается конструктор для объекта

 

thesis = new Thesis() { Name =

 

thesis (тема дипломного проекта) и происходит

8

richTextBoxTheme.Text, ProfessorId = professor.Id

инициализация его свойств. Атрибуту

 

 

};

 

ProfessorId присваивается Id объекта

 

professor, найденного в базе данных.

 

 

9

}

 

 

 

10

}

 

 

 

Добавление созданного объекта thesis в

 

коллекцию сущностей Theses из контекста

11

db.Theses.Add(thesis);

 

данных, отвечающую за хранение сущностей в

 

базе данных

foreach (Professor professor in

12db.Professors.Include("Theses"))

13{

14if (this.Professor.Name == professor.Name)

15{

28

 

 

 

 

 

 

Добавление в коллекцию Theses объекта

16

professor.Theses.Add(thesis);

professor новой темы дипломного проекта

 

 

 

 

 

 

 

thesis

 

 

 

 

 

 

 

 

 

17

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

18

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

db.SaveChanges();}

 

 

Сохранение изменений результата запроса в базе

19

 

 

 

данных

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Реализация метода обработчика события нажатия на кнопку «

Изменить

»:

 

 

 

 

 

 

 

 

 

Листинг 17.32

 

 

 

 

 

 

 

 

1

 

using (UserContext db = new UserContext())

 

 

 

2

 

{

 

 

 

 

 

 

3

 

foreach (Thesis thesis in db.Theses)

 

 

 

4

 

{

 

 

 

 

 

 

5

 

if (thesis.Name == (string)listBoxTheme.SelectedItem)

 

 

 

6

 

{

 

 

 

 

 

 

7

 

thesis.Name = richTextBoxEditTheme.Text;

 

 

 

8

 

}

 

 

 

 

 

 

9

 

}

 

 

 

 

 

 

10

 

db.SaveChanges();

 

 

 

 

 

11

 

}

 

 

 

 

29

При удалении объектов, связанных отношением «один-ко-многим» нам надо учитывать то, что по умолчанию даже если внешний ключ допускает значение null (как в данном случае свойство ProfessorId в классе Thesis),

мы не сможем просто так удалить одну модель, если она имеет ссылки на другую модель. Например, удаление дипломного руководителя в данном случае приведет к ошибке, если какой-нибудь объект Professor имеет ссылку на эту дипломный проект. В этом случае нам надо установить для внешнего ключа ProfessorId в таблице дипломных проектов ограничение

ON DELETE SET NULL. Данное ограничение позволит при удалении связанного объекта устанавливать для внешнего ключа значение null.

§17.11 Миграции

В реальных проектах модели данных изменяются по мере реализации функций. При добавлении или изменении новых сущностей или свойств схемы базы данных должны быть соответствующим образом изменены для синхронизации с приложением. Функция миграции в EF позволяет последовательно применять изменения схемы к базе данных, чтобы синхронизировать ее с моделью данных в приложении без потери существующих данных.

Добавим к существующему классу Thesis свойство для хранения аннотации к дипломному проекту:

Листинг 17.33

1

 

public class Thesis

 

 

2

{

 

 

3

 

public int Id { get; set;

}

 

4

 

public string Name { get;

set; }

5

 

public int? ProfessorId {

get; set; }

6

 

public virtual Professor Professor { get; set; }

7

 

public string Annotation { get; set; }

 

8

}

 

 

Для миграции в Visual Studio перейдем к окну Консоль диспетчера

пакетов, которое можно найти внизу VS. Если такого окна нет, то его можно

открыть, перейдя к меню Вид Другие окна Консоль диспетчера пакетов. 30