找到你要的答案

Q:How can I delete object with DbContext in c#?

Q:我怎么能删除C # DbContext对象吗?

I have this delete method:

private void btnDeleteOrderLine_Click(object sender, EventArgs e)
{
    OrderLine orderLine = (OrderLine)dgvOrderLine.SelectedRows[0].DataBoundItem;
    db.OrderLines.Remove(orderLine);
    db.SaveChanges();
    refreshGrid();
}

when I click that delete button, I get this error:

The object cannot be deleted because it was not found in the ObjectStateManager.

I found out that it is because there were two instances of Context class. So, I tried this:

private void btnDeleteOrderLine_Click(object sender, EventArgs e)
{
    OrderLine orderLine = (OrderLine)dgvOrderLine.SelectedRows[0].DataBoundItem;
    db.OrderLines.Attach(orderLine);  // added this part
    db.OrderLines.Remove(orderLine);
    db.SaveChanges();
    refreshGrid();
}

then this gave me the following error:

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

How can I fix this and delete an object from Context DbSet?

我有这个删除方法:

private void btnDeleteOrderLine_Click(object sender, EventArgs e)
{
    OrderLine orderLine = (OrderLine)dgvOrderLine.SelectedRows[0].DataBoundItem;
    db.OrderLines.Remove(orderLine);
    db.SaveChanges();
    refreshGrid();
}

当我点击删除按钮,我得到这个错误:

The object cannot be deleted because it was not found in the ObjectStateManager.

我发现这是因为有两个上下文类实例。所以,我尝试了这个:

private void btnDeleteOrderLine_Click(object sender, EventArgs e)
{
    OrderLine orderLine = (OrderLine)dgvOrderLine.SelectedRows[0].DataBoundItem;
    db.OrderLines.Attach(orderLine);  // added this part
    db.OrderLines.Remove(orderLine);
    db.SaveChanges();
    refreshGrid();
}

然后,这给了我以下错误:

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

我怎样才能解决这个删除上下文DbSet的对象?

answer1: 回答1:

You have first find the item from the context and then remove it. I have used a property called Id. This is not might be the case. You have set there the corresponding key property.

var selectedOrderLine = (OrderLine)dgvOrderLine.SelectedRows[0].DataBoundItem;

// Here using the context class we try to find if there is the 
// selected item at all 
var orderLine = db.OrderLines.SingleOrDefault(item=>item.Id == selectedOrderLine.Id);

if(orderLine!=null)
{
    // The items exists. So we remove it and calling 
    // the db.SaveChanges this will be removed from the database.
    db.OrderLines.Remove(orderLine);
    db.SaveChanges();
    refreshGrid();
}

Now let's go a bit deeper, in order we understand the following error message:

The object cannot be deleted because it was not found in the ObjectStateManager.

What is the ObjectStateManager class? Accoding to MSDN:

ObjectStateManager tracks query results, and provides logic to merge multiple overlapping query results. It also performs in-memory change tracking when a user inserts, deletes, or modifies objects, and provides the change set for updates. This change set is used by the change processor to persist modifications.

In addition to the above:

This class is typically used by ObjectContext and not directly in applications.

您首先从上下文中查找该项目,然后将其移除。我使用了一个叫id的属性,这可能不是。您设置了相应的关键属性。

var selectedOrderLine = (OrderLine)dgvOrderLine.SelectedRows[0].DataBoundItem;

// Here using the context class we try to find if there is the 
// selected item at all 
var orderLine = db.OrderLines.SingleOrDefault(item=>item.Id == selectedOrderLine.Id);

if(orderLine!=null)
{
    // The items exists. So we remove it and calling 
    // the db.SaveChanges this will be removed from the database.
    db.OrderLines.Remove(orderLine);
    db.SaveChanges();
    refreshGrid();
}

现在让我们深入一点,以便了解下列错误信息:

The object cannot be deleted because it was not found in the ObjectStateManager.

的ObjectStateManager类是什么?根据MSDN:

ObjectStateManager tracks query results, and provides logic to merge multiple overlapping query results. It also performs in-memory change tracking when a user inserts, deletes, or modifies objects, and provides the change set for updates. This change set is used by the change processor to persist modifications.

除上述:

This class is typically used by ObjectContext and not directly in applications.

answer2: 回答2:

Try using delete instead of remove and wrap it in using

using (YourContext db = new YourContext())
 {
            db.OrderLines.Attach(orderLine);  // added this part
            db.OrderLines.DeleteObject(orderLine);
            db.SaveChanges();   
  }

尝试使用删除,而不是删除和包装使用

using (YourContext db = new YourContext())
 {
            db.OrderLines.Attach(orderLine);  // added this part
            db.OrderLines.DeleteObject(orderLine);
            db.SaveChanges();   
  }
c#  .net  winforms  linq  entity-framework