在实体框架5的ObjectStateManager中找不到该对象,无法删除.处理步骤

本文关键字:删除 处理 对象 框架 实体 ObjectStateManager 找不到 | 更新日期: 2023-09-27 18:05:50

我试图使用EntityFramework 5删除对象,但我得到此错误。对象不能被删除,因为在ObjectStateManager
我使用Remove()方法,因为DeleteObject()不存在于EF5中。有人能帮我吗,我错过了什么?

对于Remove

不起作用
localDb.Customers.Remove(new Customer() { CustomerId = id });
                localDb.SaveChanges();

另一件事我尝试从msdn更改状态为已删除。但是这里它给出了一个错误,说所有的字段都应该存在。有必要得到完整的记录然后删除吗?

var customer = new Customer(){ CustomerId = id };
                localDb.Customers.Attach(customer);
                localDb.Entry(customer).State = EntityState.Deleted;
                localDb.SaveChanges();

输入吗?

在实体框架5的ObjectStateManager中找不到该对象,无法删除.处理步骤

您可以从数据库中获取该行,然后删除它,但这会导致两次数据库往返。

如果你想一次完成它,你的第二个版本与Attach将工作-只要实体尚未加载到上下文中。

您得到的错误是由EF验证引起的,该验证在任何数据库写入之前运行。

你可以像这样暂时关闭它:

bool oldValidateOnSaveEnabled = localDb.Configuration.ValidateOnSaveEnabled;
try
{
  localDb.Configuration.ValidateOnSaveEnabled = false;
  var customer = new Customer { CustomerId = id };
  localDb.Customers.Attach(customer);
  localDb.Entry(customer).State = EntityState.Deleted;
  localDb.SaveChanges();
}
finally
{
  localDb.Configuration.ValidateOnSaveEnabled = oldValidateOnSaveEnabled;
}

如果你从数据库中检索对象,那么它已经附加到上下文所以你可以删除:

db.myTable.Remove(model);


如果您只是通过post从编辑或删除视图接收模型,或者自己生成模型以避免2次访问数据库,那么EF不知道它,您会得到上面一行的错误(..),所以你设置它的状态为"Deleted",通过

通知EF:
//generate it yourself if not posted from edit/delete view
//var model = new Model { Id = 123 };
//set to delete
db.Entry(model).State = EntityState.Deleted;
db.SaveChanges();

你就不能这么做吗?

var customer = localDb.Customers.Single(o => o.CustomerId == id);
localDb.Customers.Remove(customer);
localDb.SaveChanges();
public T Delete<T>(T obj) where T : class
        {
            T existing = context.Set<T>().Find(GetKeys(obj, context));
            if (existing != null)
            {
                context.Set<T>().Remove(existing);
                context.SaveChanges();
                return existing;
            }
            return null;
        }
private object[] GetKeys<T>(T entity, DbContext context) where T : class
        {
            ObjectContext objectContext = ((IObjectContextAdapter)context).ObjectContext;
            ObjectSet<T> set = objectContext.CreateObjectSet<T>();
            var keyNames = set.EntitySet.ElementType
                                                        .KeyMembers
                                                        .Select(k => k.Name).ToArray();
            Type type = typeof(T);
            object[] keys = new object[keyNames.Length];
            for (int i = 0; i < keyNames.Length; i++)
            {
                keys[i] = type.GetProperty(keyNames[i]).GetValue(entity, null);
            }
            return keys;
        }

我知道这个问题很老了,但上面没有一个对我有用,因为我一次从多个类/服务中删除寄存器,其中每个都实例化了它自己的数据库连接上下文。

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

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

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