无法删除该对象,因为在ObjectStateManager中找不到该对象

时间:2011-10-17 08:28:57

标签: c# asp.net entity-framework-4

我收到此错误“无法删除该对象,因为在ObjectStateManager中找不到该对象。”

我的代码是:

    protected MyEntities sqlEntities;

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

10 个答案:

答案 0 :(得分:154)

这意味着实体未附加(它没有被相同的上下文实例加载)。试试这个:

protected MyEntities sqlEntities;

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

答案 1 :(得分:60)

Ladislav Mrnka对答案的一点澄清(应该是接受的答案)。

如果像我一样,你的代码格式如下:

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

也许这看起来很明显,但我最初并不清楚有必要指定实体来附加,而不仅仅是上下文

答案 2 :(得分:10)

正好解释Kjartans的解释:

我有:

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

答案 3 :(得分:2)

您可以编写此代码:

var x=yourquery.FirstOrDefault(); 

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

答案 4 :(得分:2)

I know this question is quite old but none of the above worked for me since i was deleting registers from more than one class/service and each of of them was instantiating it's own database connection context.

What i did to solve it was to send the first created context to the rest of the classes/services that where going to access the database.

For example, my serviceA was going to delete some of it's registers and call serviceB and serviceC to do the same with their registers.

I would then delete my registers on serviceA and pass as a parameter the context created on the serviceA to serviceB and serviceC.

答案 5 :(得分:1)

如果上述情况均无效,您可以尝试以下解决方案:

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

答案 6 :(得分:0)

您应确保您的对象存在于您要删除的列表中, 你应该把以下条件

  
    

if(context.entity.contains(your object))

         

将其删除。

  

如果你有一个复杂的平等条件你应该覆盖 在实体类中使用相等的方法来使你的条件相等, 为扩展方法“entity.contains”

找到正确的方法

答案 7 :(得分:0)

确保传递给Remove(Entity)的模型与数据库记录完全相同。

有时可以通过模型传递一些字段,例如Id或Date。如果您以表格形式发布,请将这些内容保存到@ html.Hiddenfor中。

最好的方法是传递ID并使用Find(Id)方法获取实体并将其传递给Remove(Entity)

希望这有助于某人。

答案 8 :(得分:0)

我解决了这个问题。只需复制以下代码:

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

答案 9 :(得分:0)

在我的情况下,只有一个上下文,但是我的实体带有'AsNoTracking'选项