Невозможно удалить объект, потому что он не был найден в ObjectStateManager - PullRequest
113 голосов
/ 17 октября 2011

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

Мой код:

    protected MyEntities sqlEntities;

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

Ответы [ 9 ]

154 голосов
/ 17 октября 2011

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

protected MyEntities sqlEntities;

public virtual void Delete(TEntity entity)
{
    sqlEntities.Attach(entity);
    sqlEntities.DeleteObject(entity);
    sqlEntities.SaveChanges();
}
60 голосов
/ 17 октября 2013

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

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

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();
}

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

10 голосов
/ 30 января 2014

Просто чтобы понять объяснение Кьяртана:

У меня было:

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;      
        }
    }

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

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;
        }
    }
2 голосов
/ 09 декабря 2016

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

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

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

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

2 голосов
/ 03 сентября 2013

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

var x=yourquery.FirstOrDefault(); 

sqlEntities.DeleteObject(x);
sqlEntities.SaveChanges();
1 голос
/ 07 декабря 2016

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

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

0 голосов
/ 25 сентября 2018

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

sqlEntities.Attach(entity);
sqlEntities.Remove(entity);
sqlEntities.SaveChanges();
0 голосов
/ 08 ноября 2016

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

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

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

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

0 голосов
/ 15 сентября 2015

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

if (context.entity.contains (ваш объект).равенство, чтобы получить правильный путь для метода расширения "entity.contains"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...