Большинство операций с данными представляют собой CRUD-операции (Create, Read, Update, Delete), то есть получение данных, создание, обновление и удаление. Entity Framework позволяет легко производить данные операции.
Для примеров с операциями возьмем простенькую модель Phone:
1 2 3 4 5 6 |
public class Phone { public int Id { get; set; } public string Name { get; set; } public int Price { get; set; } } |
И следующий класс контекста данных:
1 2 3 4 5 6 7 |
public class PhoneContext : DbContext { public PhoneContext() : base("DefaultConnection") { } public DbSet<Phone> Phones { get; set; } } |
Добавление
Для добавления применяется метод Add()
у объекта DbSet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
using (PhoneContext db = new PhoneContext()) { Phone p1 = new Phone { Name = "Samsung Galaxy S7", Price = 20000 }; Phone p2 = new Phone { Name = "iPhone 7", Price = 28000 }; // добавление db.Phones.Add(p1); db.Phones.Add(p2); db.SaveChanges(); // сохранение изменений var phones = db.Phones.ToList(); foreach (var p in phones) Console.WriteLine("{0} - {1} - {2}", p.Id, p.Name, p.Price); } |
После добавления надо сохранить все изменения с помощью метода SaveChanges()
.
Консольный вывод:
1 2 |
1 - Samsung Galaxy S7 - 20000 1 - iPhone 7 - 28000 |
Редактирование
Контекст данных способен отслеживать изменения объектов, поэтому для редактирования объекта достаточно изменить его свойства и после этого вызвать метод SaveChanges()
:
1 2 3 4 5 6 7 8 |
using (PhoneContext db = new PhoneContext()) { // получаем первый объект Phone p1 = db.Phones.FirstOrDefault(); p1.Price = 30000; db.SaveChanges(); // сохраняем изменения } |
Но рассмотрим другую ситуацию:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Phone p1; using (PhoneContext db = new PhoneContext()) { p1 = db.Phones.FirstOrDefault(); } using (PhoneContext db = new PhoneContext()) { if(p1!=null) { p1.Price = 60000; db.SaveChanges(); } } |
Так как объект Phone получен в одном контексте, а изменяется для другого контекста, который его не отслеживает. В итоге изменения не сохранятся. Чтобы изменения сохранились, нам явным образом надо установить для его состояния значение EntityState.Modified:
1 2 3 4 5 6 7 8 9 |
using (PhoneContext db = new PhoneContext()) { if(p1!=null) { p1.Price = 60000; db.Entry(p1).State = EntityState.Modified; db.SaveChanges(); } } |
Удаление
Для удаления объекта применяется метод Remove() объекта DbSet:
1 2 3 4 5 6 7 8 9 |
using (PhoneContext db = new PhoneContext()) { Phone p1 = db.Phones.FirstOrDefault(); if(p1!=null) { db.Phones.Remove(p1); db.SaveChanges(); } } |
Но как и в случае с обновлением здесь мы можем столкнуться с похожей проблемой, когда объект получаем из базы данных в пределах одного контекста, а пытаемся удалить в другом контексте. И в этом случае нам надо установить вручную у объекта состояние EntityState.Deleted:
1 2 3 4 5 6 7 8 |
using (PhoneContext db = new PhoneContext()) { if(p1!=null) { db.Entry(p1).State = EntityState.Deleted; db.SaveChanges(); } } |
Метод Attach
Если объект получен в одном контексте, а сохраняется в другом, то мы можем устанавливать у него вручную состояния EntityState.Updated или EntityState.Deleted. Но есть еще один способ: с помощью метода Attach у объекта DbSet мы можем прикрепить объект к текущему контексту данных:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
Phone p1; using (PhoneContext db = new PhoneContext()) { p1 = db.Phones.FirstOrDefault(); } // редактирование using (PhoneContext db = new PhoneContext()) { if(p1!=null) { db.Phones.Attach(p1); p1.Price = 999; db.SaveChanges(); } } // удаление using (PhoneContext db = new PhoneContext()) { if(p1!=null) { db.Phones.Attach(p1); db.Remove(p1); db.SaveChanges(); } } |