Объект нельзя удалить, поскольку он не найден в ObjectStateManager

Я получаю эту ошибку "Объект не может быть удален, потому что он не найден в ObjectStateManager."

Мой код:

    protected MyEntities sqlEntities;

    public virtual void Delete(TEntity entity)
    {
        System.Type t = typeof(TEntity);
        sqlEntities.DeleteObject(entity);
        sqlEntities.SaveChanges();
    }

Ответ 1

Это означает, что объект не присоединен (он не был загружен одним и тем же экземпляром контекста). Попробуйте следующее:

protected MyEntities sqlEntities;

public virtual void Delete(TEntity entity)
{
    sqlEntities.Attach(entity);
    sqlEntities.DeleteObject(entity);
    sqlEntities.SaveChanges();
}

Ответ 2

Небольшое уточнение ответа Ладислава Мрнки (который должен быть принятым ответом).

Если вам нравится я, у вас есть код в таком формате:

using (var context = new MyDataContext())
{
    context.MyTableEntity.Remove(EntytyToRemove);
    var nrOfObjectsChanged = context.SaveChanges();
}

.. затем это то, что вы хотите сделать:

using (var context = new MyDataContext())
{
    // Note: Attatch to the entity:
    context.MyTableEntity.Attach(EntityToRemove);

    context.MyTableEntity.Remove(EntityToRemove);
    var nrOfObjectsChanged = context.SaveChanges();
}

Возможно, это кажется очевидным, но изначально мне не было понятно, что необходимо указывать сущность, к которой нужно привязываться, а не только контекст.

Ответ 3

Просто для защиты от объяснения Кьяртанса:

У меня было:

public Project DeleteProject(int id)
    {
        using (var context = new Context())
        {
            var p = GetProject(id);
            context.Projects.Remove(p);
            context.SaveChanges();
            return p;
        }
    }

Проблема заключается в том, что я использовал свой собственный метод (GetProject()), чтобы получить объект (следовательно, используя другой контекст для загрузки объекта):

public Project GetProject(int id)
    {
        using (var context = new Context())
        {
            var project = context.Projects
                .Include(p => p.Reports.Select(q => q.Issues.Select(r => r.Profession)))
                .Include(p => p.Reports.Select(q => q.Issues.Select(r => r.Room)))
                .SingleOrDefault(x => x.Id == id);
            return project;      
        }
    }

Одним из решений может быть присоединение загруженного объекта как состояния Kjartan, другое может быть моим решением, для загрузки объекта в том же контексте:

public Project DeleteProject(int id)
    {
        using (var context = new Context())
        {
            var p = context.Projects.SingleOrDefault(x => x.Id == id);
            if (p == null)
                return p;

            context.Projects.Remove(p);
            context.SaveChanges();
            return p;
        }
    }

Ответ 4

Вы можете написать этот код:

var x=yourquery.FirstOrDefault(); 

sqlEntities.DeleteObject(x);
sqlEntities.SaveChanges();

Ответ 5

Я знаю, что этот вопрос довольно старый, но ни один из вышеперечисленных не работал у меня, так как я удалял регистры из более чем одного класса/службы, и каждый из них создавал экземпляр собственного контекста подключения к базе данных.

Что я сделал для его решения, так это отправить первый созданный контекст в остальные классы/службы, которые будут обращаться к базе данных.

Например, мой serviceA собирался удалить некоторые из его регистров и вызвать serviceB и serviceC, чтобы сделать то же самое с их регистрами.

Затем я бы удалил свои регистры на serviceA и передал в качестве параметра контекст, созданный на serviceA до serviceB и serviceC.

Ответ 6

Если ни одно из вышеперечисленных действий не работает, вы можете попробовать это решение:

context.Entry(yourObject).State = System.Data.Entity.EntityState.Deleted; context.SaveChanges();

Ответ 7

Вы должны быть уверены, что ваш объект существует в списке, который вы пытаетесь удалить, вы должны поставить следующее условие

if (context.entity.contains(ваш объект))

     

удалите его.

если у вас есть сложное условие равенства , вы должны переопределить равный метод в классе сущности, чтобы поставить ваше условие равенства, для получения правильного пути для метода расширения "entity.contains"

Ответ 8

Убедитесь, что модель, проходящая в Remove (Entity), точно такая же, как и запись базы данных.

Несколько раз его можно было передать модели с некоторыми полями, такими как Id или Date. храните их в @html.Hiddenfor, если вы публикуете форму.

Лучший способ - передать идентификатор и получить объект, используя метод Find (Id), и передать его Remove (Entity)

Надеюсь, это поможет кому-то.

Ответ 9

Я получил эту проблему и решил ее. Просто скопируйте приведенный ниже код:

sqlEntities.Attach(entity);
sqlEntities.Remove(entity);
sqlEntities.SaveChanges();