Подтвердить что ты не робот

Заявление об обновлении, вставке или удалении приложения влияет на неожиданное количество строк (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;
}

Но ошибка не поймана. Спасибо вам

4b9b3361

Ответ 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);
    }