Материал: Глава 17.1 Entity Framework

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

ОСНОВНЫЕ ОПЕРАЦИИ С ДАННЫМИ

Большинство операций с данными представляют собой CRUD-

операции (Create, Read, Update, Delete), то есть получение данных, создание,

обновление и удаление. Entity Framework позволяет легко производить данные операции.

Для примеров с операциями возьмем модель User, созданную в предыдущем параграфе:

Листинг 17.7

1

public partial class User

 

2

{

 

3

public int Id { get; set; }

 

4

public string Log { get; set; }

 

5

public string Password { get; set; }

 

6

}

 

 

И следующий класс контекста данных:

 

Листинг 17.8

 

 

 

1

public partial class UserContainer : DbContext

 

2

{

 

3

public UserContainer() : base("name=UserContainer")

 

{}

 

 

 

4

protected override void

 

OnModelCreating(DbModelBuilder modelBuilder)

 

 

 

5

{

 

6

throw new UnintentionalCodeFirstException();

 

7

}

 

8

public virtual DbSet<User> Users { get; set; }

 

9

}

 

 

Добавление (CREATE)

Создадим форму добавления новых объектов:

Рисунок 1

 

Для добавления применяется метод Add() у объекта DbSet:

 

Листинг 17.9

 

 

 

1

using (UserContainer db = new UserContainer())

 

2

{

 

3

User user = new User() { Log = textBoxLog.Text,

 

Password = textBoxPassword.Text };

 

 

 

4

db.Users.Add(user);

 

5

db.SaveChanges();

 

6

}

 

7

listBoxUsers.Items.Clear();

 

8

using (UserContainer db = new UserContainer())

 

9

{

 

10

foreach (var item in db.Users)

 

11

{

 

12

listBoxUsers.Items.Add(item.Log);

 

13

}

 

14

}

 

После добавления надо сохранить все изменения с помощью метода

SaveChanges(). В строках 7-13 происходит обновление списка – в него загружаются все элементы из таблицы Users.

Рисунок 2

Обновление (UPDATE)

Создадим форму редактирования объектов, хранящихся в таблице

Users:

Рисунок 3

Контекст данных способен отслеживать изменения объектов, поэтому для редактирования объекта достаточно изменить его свойства и после этого вызвать метод SaveChanges():

 

Листинг 17.10

 

 

 

1

User user = null;

 

 

 

 

2

using (UserContainer db = new UserContainer())

 

 

 

 

3

{

 

 

 

 

4

foreach (var item in db.Users)

 

 

 

 

5

{

 

 

 

 

6

if (item.Log == (string)listBoxUsers.SelectedItem)

 

 

 

 

7

{

 

 

 

 

8

user = db.Users.Find(item.Id);

 

 

 

 

9

}

 

 

 

 

10

}

 

 

 

 

11

user.Log = textBoxNewLog.Text;

 

 

 

 

12

user.Password = textBoxNewPassword.Text;

 

 

 

 

13

db.SaveChanges();

 

 

 

 

14

}

 

Здесь user – объект, который выбирается из списка listBoxUsers для дальнейшего редактирования.

Для поиска искомого объекта в базе данных используется метод Find

класса DbSet, использующий в качестве параметра значение первичного ключа, чтобы найти сущность, отслеживаемую контекстом данных. Если сущность не найдена в контексте, запрос отправляется в базу данных для поиска сущности там. Если сущность не найдена в контексте или в базе данных, возвращается значение NULL.

Рассмотрим ситуацию, где объект User будет получен в одном контексте, а изменять свои значения будет для другого контекста, который его не отслеживает:

 

Листинг 17.11

 

 

 

1

User user = null;

 

2

using (UserContainer db = new UserContainer())

 

3

{

 

4

foreach (var item in db.Users)

 

5

{

 

6

if (item.Log == (string)listBoxUsers.SelectedItem)

 

7

{

 

8

user = db.Users.Find(item.Id);

 

9

}

 

10

}

 

11

}

 

12

using (UserContainer db = new UserContainer())

 

13

{

 

14

user.Log = textBoxNewLog.Text;

 

15

user.Password = textBoxNewPassword.Text;

 

16

db.SaveChanges();

 

17

}

 

 

В итоге при попытке обновления изменения не сохранятся. Чтобы

изменения сохранились, нам явным образом надо установить для состояния объекта значение EntityState.Modified:

 

Листинг 17.12

 

 

 

1

using (UserContainer db = new UserContainer())

 

2

{

 

3

user.Log = textBoxNewLog.Text;

 

4

user.Password = textBoxNewPassword.Text;

 

5

db.Entry(user).State = EntityState.Modified;

 

6

db.SaveChanges();

 

7

}

 

 

Метод Entry получает объект DbEntityEntry для данной сущности из

контекста UserContainer, предоставляющий доступ к информации о сущности и возможность выполнять действия с этой сущностью. В нашем случае с помощью свойства State изменяется состояние измененной

сущности для возможности присоединения ее к контексту и дальнейшей ее отправки в базу данных при вызове метода SaveChanges.

Удаление (DELETE)

Создадим форму удаления объектов, хранящихся в таблице Users:

 

Рисунок 4

 

Для удаления объекта применяется метод Remove() объекта DbSet:

 

Листинг 17.13

 

 

 

1

User user = null;

 

2

using (UserContainer db = new UserContainer())

 

3

{

 

4

foreach (var item in db.Users)

 

5

{

 

6

if (item.Log == (string)listBoxUsers.SelectedItem)

 

7

{

 

8

user = db.Users.Find(item.Id);

 

9

}

 

10

}

 

11

db.Users.Remove(user);

 

12

db.SaveChanges();

 

13

}

 

Метод Remove помечает сущность, переданную в параметры, как удаленную, так что она будет удалена из базы данных при вызове

SaveChanges. Обратите внимание, что перед вызовом этого метода объект должен существовать в контексте в каком-то другом состоянии.

Но, как и в случае с обновлением здесь мы можем столкнуться с похожей проблемой, когда объект получаем из базы данных в пределах одного контекста, а пытаемся удалить в другом контексте. И в этом случае нам надо установить вручную у объекта состояние EntityState.Deleted:

Источник: https://studfile.net/preview/16573803/