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

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

我的代码是:

    protected MyEntities sqlEntities;


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

It means that entity is not attached (it was not loaded by the same context instance). Try this:

protected MyEntities sqlEntities;


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

您可以编写以下代码:

var x=yourquery.FirstOrDefault();


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

只是对 Ladislav Mrnka 的回答的一个小小的澄清(这应该是可以接受的答案)。

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

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

..then this what you want to do:

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


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

也许这是显而易见的,但是最初我并不清楚是否有必要指定要附加的 实体,而不仅仅是 背景

正确的解释是:

I had:

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

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

If (context.entity.include (your object))

remove it.

如果有一个复杂的等式条件 < strong > ,则应重写 在实体类 中放置你的条件为相等, to get the right way for an extension method "entity.contains"

Make sure the model passing into Remove(Entity) is exactly same as the database record.

Some times its possible to pass the model with out some fields like Id or Date. keep those into @html.Hiddenfor if you posting as form.

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

希望这对谁有帮助。

如果上述方法都不管用,你可以试试这个办法:

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

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.

我所做的就是将第一个创建的上下文发送给其他类/服务,这些类/服务将访问数据库。

例如,我的 serviceA将删除它的一些寄存器,并调用 serviceBserviceC对它们的寄存器执行相同的操作。

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

我得到这个问题并解决它。只要复制以下代码:

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

在我的例子中,有一个上下文,但是我得到了带有“ AsNoTrace”选项的实体