Заявление об обновлении, вставке или удалении приложения влияет на неожиданное количество строк (0) EntityFramework
Я продолжаю получать следующую ошибку, когда я пытаюсь сохранить изменения, внесенные в контекст:
Сохранить выражение о обновлении, вставке или удалении, вызванное неожиданным количество строк (0). Объекты могут быть изменены или удалены, поскольку объекты загружены. Обновить записи ObjectStateManager.
У меня есть следующие классы:
Person
public class Person : IPerson
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Name
{
get
{
return FirstName + " " + LastName;
}
set{}
}
public string Email { get; set; }
public DateTime? LastModified { get; set; }
public virtual ICollection<Result> Results { get; set; }
}
UserProfile
public class UserProfile : Person
{
public UserProfile()
{
Faculty = new Faculty();
Projects = new Collection<Project>();
Results = new Collection<Result>();
}
public string UserName { get; set; }
public string CNP { get; set; }
public virtual Faculty Faculty { get; set; }
public virtual ICollection<Project> Projects { get; set; }
}
Результат
public abstract class Result:INamedEntity
{
protected Result()
{
ResultType = new ResultType();
}
public int Id { get; set; }
public string Name{get;set;}
public virtual ResultType ResultType { get; set; }
public virtual ICollection<Person> People { get; set; }
public DateTime? LastModified { get; set; }
}
После того, как я добавлю значение в контекст, используя:
_ctx.Users.Single(u => u.Id == userId).Results.Add(result);
Я получаю сообщение об ошибке при вызове _ctx.SaveChanges()
Обновлена моя функция:
public bool Save()
{
try
{
_ctx.SaveChanges();
}
catch (OptimisticConcurrencyException)
{
((IObjectContextAdapter)_ctx).ObjectContext.Refresh(RefreshMode.ClientWins,_ctx.Users);
((IObjectContextAdapter)_ctx).ObjectContext.Refresh(RefreshMode.ClientWins,_ctx.Results);
_ctx.SaveChanges();
}
return true;
}
Но ошибка не поймана.
Спасибо вам
Ответы
Ответ 1
Выяснил это.
Проблема заключалась в том, что двое из нас работали над этим проектом, и мой коллега создал свой собственный экземпляр DBContext
, он обновлял один, а другой. Поэтому для тех, кто когда-либо сталкивался с этой проблемой в будущем, убедитесь, что у вас нет двух разных экземпляров вашего DBContext
в то же время
Ответ 2
Добавьте это в свой edit.cshtml
@Html.HiddenFor(model => model.Id)
У меня была эта проблема, и я обнаружил, что идентификатор встречается как 0, так как его не было на странице.
У меня также есть это на моем ViewModel (я использую подход модели представления)
[HiddenInput(DisplayValue = false)]
[Key]
public int Id { get; set; }
Ответ 3
Ваше исключение означает, что между временем, когда вы извлекли данные из базы данных и изменили его, ваши данные были изменены.
По умолчанию Entity Framework реализует оптимистичную модель concurrency. Это означает, что блокировки не хранятся на данных в источнике данных между тем, когда данные запрашиваются и данные обновляются. MSDN
как управлять concurrency в контексте объекта. MSDN
Или следуйте этому ответу, который обновляет контекст. fooobar.com/questions/234462/...
Ответ 4
Для меня проблема заключалась в том, что я не установил правильные привязки :
public ActionResult Edit([Bind(Include = "VehicleID,Name,CreateDate,PowerPS,DrivenKM")] Car car)
{ ... }
Идентификатор VehicleID был сопоставлен с неправильным идентификатором, поэтому Entity Framework всегда получал 0 в качестве первичного ключа.
Ответ 5
Если бы вы столкнулись с этой проблемой, и вам не помогли бы избежать вышеупомянутых решений, возможно, вы сможете попробовать это. У меня также была эта странная проблема, и способ, которым я смог ее устранить, - это установить поле в первичный ключ и настроить его автоматически или установить на Identity. Скажем, у вас есть таблица Person, и у вас есть personID, возможно, установите его в первичный ключ и убедитесь, что он автоматически увеличивается.
Ответ 6
Существует конфликт, так как вы используете оптимистичную блокировку. Устранение проблем concurrency с использованием записей ObjectStateManager и сохранение изменений снова. Некоторые примеры кода находятся в MSDN сайте.
Ответ 7
Я столкнулся с этим, когда googleing. У меня было такое же сообщение об ошибке, но причина оказалась в том, что я не установил некоторые обязательные ненулевые значения.
Возможно, это открытие помогает кому-то.
Ответ 8
Я столкнулся с этим сообщением об ошибке. В результате моей ошибки были конфликты первичных/внешних ключей. Я ввел некоторые новые данные в свою БД и мои внешние значения ключа были отключены (ошибка в моей загрузке script).
С помощью SQL Profiler вы можете отслеживать повреждающую вставку script, это, скорее всего, поможет вам узнать, в чем проблема с обновлением.
Надеюсь, это поможет кому-то еще с подобными проблемами.
Ответ 9
Спасибо Терри,
Добавьте это:
НЕ добавляйте атрибут [Обязательный] к вашему ключу/идентификатору в случае лесов.
Это останавливает ваш контекст от вытаскивания ключа/идентификатора из URL-адреса.
Также:
Это случилось со мной в контроллере эшафотов после миграции
который включал новые булевы поля в модели. Эти поля были
не установлено.
Ответ 10
Убедитесь, что вы передаете идентификатор для обеих таблиц модели из представления. В вашем случае это ключ для таблицы Person и UserProfile.
Если вам не нужно показывать идентификатор на странице, вы можете добавить
@Html.HiddenFor(model = > model.PersonId) и @Html.HiddenFor(model = > model.UserProfileId)
Ответ 11
Я столкнулся с этой ошибкой при создании проекта, даже пытаясь сделать простую вставку.
Мы генерировали EF-модель из уже существующей базы данных, а структура автоматически устанавливала Entity Key = True
для нескольких полей.
Установка всех параметров, кроме ID в False
, решила проблему.
Ответ 12
Я не знаю, что именно было не так, но я просто сделал эти шаги, и это было разрешено. (Я надеюсь, что вы сможете это решить, поскольку я смог это сделать)
Шаги выглядят следующим образом:
(1) Добавьте новый контроллер, используя строительные леса, на основе вашей таблицы edmx и контекста DB EF файла.
(2) Теперь, когда изменения сохранения создают проблему, это метод редактирования.
(3) Теперь скопируйте метод редактирования/весь контроллер, сделанный из лесов, и вставьте его в исходный контроллер.
(4) теперь просто создайте программу и Voila, в которую вы можете пойти.
Обновление
Я узнал, что для данных, которые нужно отредактировать из представления, все поля должны быть отправлены для записи снова на контроллер. Если во время издания какое-либо из полей таблицы сущностей отсутствует, оно не будет разрешено для редактирования. Особенно, если PK находится в Label и отправляется контроллеру для редактирования, тогда он будет генерировать эту ошибку.
Ответ 13
В моем случае у меня был составной ключ и он пытался обновить его часть (3 столбца представляют собой составной ключ, из которого я обновлял только третий столбец), но EF не позволял изменять значения ключа для того же объект, я достиг обновления записи через:
Context.Database.ExecuteSqlCommand(udpateCommand);
Ответ 14
Ну, я также столкнулся с этой ошибкой concurrency при работе с Entity Framework 6.13 с использованием Code First. И я также много часов боролся, прежде чем решить это сам. Так что это может помочь кому-то там. Таблица была создана с составными первичными ключами, и сегодня я изменил структуру таблицы и сделал вместо одного составного ключа только один первичный ключ (с помощью AutoIncrement) и обновил таблицу через миграции с помощью конфигураций fluent-api. Таблица обновилась, но первичный ключ не был обновлен с помощью AutoIncrement, и всякий раз, когда я пытался добавить запись, она обнаружила ошибку concurrency. Итак, когда я установил автоинкремент поля и ошибка исчезла. Надеюсь, это помогает.
Ответ 15
добавьте следующую перегрузку в мой класс DbContext:
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
public class MyDbContext: DbContext {
...
public int SaveChanges(bool refreshOnConcurrencyException, RefreshMode refreshMode = RefreshMode.ClientWins) {
try {
return SaveChanges();
}
catch (DbUpdateConcurrencyException ex) {
foreach (DbEntityEntry entry in ex.Entries) {
if (refreshMode == RefreshMode.ClientWins)
entry.OriginalValues.SetValues(entry.GetDatabaseValues());
else
entry.Reload();
}
return SaveChanges();
}
}
}
Затем называется SaveChanges(true)
, где это применимо.
Ответ 16
Я исправил некоторый код, который выдавал то же сообщение об ошибке при попытке обновить запись. Сначала я имел следующий код:
[HttpPost]
public ActionResult Edit(Project project)
{
if (ModelState.IsValid)
{
entity.Entry(project).State = EntityState.Modified;
entity.SaveChanges();
return RedirectToAction("Index", "Home");
}
return View(project);
}
Вместо следующего кода
[HttpPost]
public ActionResult Edit(Project project)
{
if (ModelState.IsValid)
{
entity.Entry(project).State = EntityState.Added;
entity.SaveChanges();
return RedirectToAction("Index", "Home");
}
return View(project);
}