23

我正在尝试使用 EntityFramework 5 删除对象,但出现此错误。 无法删除该对象,因为它在 ObjectStateManager 中找不到
我正在使用EF5 中不存在的Remove()方法。DeleteObject()谁能帮助我错过什么?

这不适用于删除

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

有什么输入吗?

4

5 回答 5

37

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

如果您想一次性完成,您的第二个版本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;
}
于 2013-03-26T13:25:37.320 回答
18

如果您从数据库中检索对象,则它已经附加到上下文中,因此您可以通过以下方式删除:

db.myTable.Remove(model);

但是,
如果您刚刚从编辑或删除视图中收到模型,或者自己生成它以避免两次访问数据库,那么 EF 不知道它并且您在上面的行中遇到错误(..在 ObjectStateManager 中找不到..)所以您将其状态设置为“已删除”以通过以下方式通知 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();
于 2014-09-02T17:56:09.427 回答
4

你能做到这一点吗?

var customer = localDb.Customers.Single(o => o.CustomerId == id);
localDb.Customers.Remove(customer);
localDb.SaveChanges();
于 2013-03-26T13:25:32.423 回答
1
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;
        }
于 2016-05-24T08:56:24.463 回答
0

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

我为解决它所做的是将第一个创建的上下文发送到要访问数据库的其余类/服务。

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

然后我会删除我的寄存器serviceA并将在serviceAtoserviceBserviceC.

于 2016-12-09T12:48:57.390 回答