Как максимально эффективно использовать Entity Framework (v4.0 или выше) в веб-приложении ASP MVC3? Моя основная проблема связана с характером веб-запроса-ответа, кажется, мне нужно вручную отслеживать объекты, отображаемые в форме, в БД, чтобы выполнять операции CUD. Например. как предлагается в Редактирование и обновление сущности Entity Framework в ASP. NET MVC, это кажется ужасно ручным. Есть ли способ сохранить мой контекст в моем сеансе так, чтобы EF выполняла всю работу за меня?
Получение максимальной отдачи от Entity Framework в веб-приложении ASP MVC
Ответы:
Не храните ObjectContext
в сеансе. Используйте новый контекст для обработки каждого запроса. Здесь вы можете прочитать кое-что о долгоживущих контекстах. Если вы используете долгоживущий контекст, хранящийся в сеансе, у вас будет большая проблема с загрузкой свежих данных. Также, если ваш пользователь откроет ваше приложение на нескольких вкладках браузера (= один и тот же сеанс), вы можете получить очень неожиданные результаты.
Если вы хотите обновить только скалярные значения (без изменений в свойствах навигации), вы можете использовать:
Вставить сценарий:
[HttpPost]
public ActionResult Insert(MyEntity entity)
{
using (var context = new MyContext())
{
context.MyEntities.AddObject(entity);
context.SaveChanges();
}
...
}
Сценарий обновления с полностью отсоединенным объектом:
[HttpPost]
public ActionResult Update(MyEntity entity)
{
using (var context = new MyContext())
{
context.MyEntities.Attach(entity);
context.ObjectStateManager.ChangeObjecState(entity, EntityState.Modified);
context.SaveChanges();
}
...
}
Сценарий обновления с загрузкой объекта сначала из БД:
[HttpPost]
public ActionResult Update(MyEntity entity)
{
using (var context = new MyContext())
{
int id = entity.Id;
context.MyEntities.Single(e => e.Id == id); // You must load the record first
context.MyEntities.ApplyCurrentValues(entity);
context.SaveChanges();
}
...
}
Удалить сценарий:
[HttpPost]
public ActionResult Delete(int id)
{
using (var context = new MyContext())
{
var entity = context.MyEntities.Single(e => e.Id == id);
context.MyEntities.DeleteObject(entity);
context.SaveChanges();
}
...
}
Можно удалить объект, не загружая его предварительно, но если объект имеет какое-либо отношение, это создает много проблем.
Если вы хотите изменить отношения, это может включать использование либо UpdateMode
/ TryUpdateModel
, как обсуждалось здесь или отслеживание изменений вручную, как описано здесь. Простые обновления отношения к ассоциации внешнего ключа ( описание такое же, даже если вы не используете код сначала), с предыдущими примерами все еще можно справиться.
Find
доступен только в DbContext API = EF 4.1. Тот же метод существует в EFv4 и называетсяGetObjectByKey
, но вы должны передать ключ объекта в качестве параметра, что не так просто с POCO. Вот пример: stackoverflow.com/questions/5273416/ 08.04.2011