Статья была загружена в один экземпляр DbContext, и вы пытаетесь сохранить его в другом экземпляре.Сущность должна быть связана с новым контекстом перед сохранением.(Т. Е. Attach
или Update
). Однако я не рекомендую такой подход.
Как правило, следует избегать передачи объектов в веб-клиент и из него.Если вы принимаете сущность для веб-клиента, очень просто найти вызов, передающий измененную сущность на сервер, применить точку останова и изменить содержимое с помощью отладчика, прежде чем возобновить работу.Если сервер просто присоединяет объект к контексту и сохраняет изменения, я могу изменить данные так, как это не должно разрешать приложение.Это также включает в себя отправку клиенту большего количества информации, чем обычно требуется.
Вы также сталкиваетесь с проблемой, заключающейся в том, что данные, поддерживающие сущность, загруженную в один момент в текущем сеансе, были изменены другим сеансом междувремя, когда вы читаете данные, и время, когда вы готовы их обновить.Системы не должны просто присоединять и перезаписывать данные, не проверив сначала (с помощью чего-то вроде метки времени или последнего изменения даты / времени), что данные не обновлялись с момента загрузки объекта.Оттуда система может предпринять соответствующее действие.(зарегистрируйте, что данные будут перезаписаны, перезаписаны или объединены, и уведомите пользователя о необходимости просмотреть их изменения.)
edit: обрисовать пример.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Ida,description,UserId,Idc,titre,image")] Article article, HttpPostedFileBase image)
{
if (!ModelState.IsValid)
{
ViewBag.Idc = new SelectList(db.Categories, "Id", "libelle", article.Idc);
return View(article);
}
using (var db = new IdentityDBEntities())
{
var existingArticle = db.Articles.Single(x => x.ArticleId == article.ArticleId);
if (existingArticle.RowVersion != article.RowVersion) // Or compare LastModifiedDateTime etc.
{
// Set a validation state to tell the user that the article had changed since they started editing. Perhaps merge values across, but send the article back.
return View(existingArticle);
}
if (image != null)
existingArticle.image = image.FileName;
existingArticle.UserId = System.Web.HttpContext.Current.User.Identity.GetUserId(); // can this be updated?
db.SaveChanges();
}
return RedirectToAction("Index");
}
Ключевые отличия: DbContextодноразовые, поэтому должны быть завернуты в блок using
.Мы загружаем статью из контекста, проверяем, была ли она изменена с момента ее первоначальной загрузки.(другие проверки правильности, чтобы убедиться, что пользователь может изменить эту статью, также было бы целесообразно), если она не устарела и действительна, перенесите поля в другое место и сохраните изменения.