无法删除对象,因为在ObjectStateManager中没有找到.处理步骤

本文关键字:处理 ObjectStateManager 删除 对象 因为 | 更新日期: 2023-09-27 18:11:21

我得到这个错误"对象不能被删除,因为它没有在ObjectStateManager中找到。"

我的代码是:
    protected MyEntities sqlEntities;
    public virtual void Delete(TEntity entity)
    {
        System.Type t = typeof(TEntity);
        sqlEntities.DeleteObject(entity);
        sqlEntities.SaveChanges();
    }

无法删除对象,因为在ObjectStateManager中没有找到.处理步骤

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

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

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

这似乎是显而易见的,但我最初并不清楚有必要指定要附加的实体,而不仅仅是上下文

只是为了恰当地解释:

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

如果以上都不起作用,您可以尝试以下解决方案:

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

我知道这个问题很老了,但以上都不适合我,因为我正在从多个类/服务中删除寄存器,并且每个都在实例化它自己的数据库连接上下文。

为了解决这个问题,我将第一个创建的上下文发送给将要访问数据库的其他类/服务。

例如,我的serviceA要删除它的一些寄存器,并调用serviceBserviceC对它们的寄存器做同样的事情。

然后我将删除serviceA上的寄存器,并将在serviceA上创建的上下文作为参数传递给serviceBserviceC

你可以这样写代码:

var x=yourquery.FirstOrDefault(); 
sqlEntities.DeleteObject(x);
sqlEntities.SaveChanges();

您应该确保您的对象存在于您试图从中删除的列表中,您应该输入以下条件

如果(context.entity

。包含(对象))

删除它。

如果你有一个复杂的相等条件你应该重写在实体类中使用equal方法来放置相等条件,获取扩展方法"entity.contains"

的正确方法

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

有时可以传递模型,但不包含一些字段,如Id或Date。将它们保存在@html中。隐藏,如果你张贴的形式。

最好的方法是传递ID并使用Find(ID)方法获取实体,然后传递给Remove(entity)

我得到了这个问题并解决了它。复制下面的代码:

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

在我的情况下,有一个上下文,但我得到的实体与'AsNoTracking'选项