将实体的状态设置为Deleted会将实体从dbContext中删除

use*_*216 4 c# state entity-framework dbcontext

我对实体框架比较陌生。最近,我发现这种奇怪的行为(在我看来)确实使我感到困惑。

如果将跟踪实体的状态设置为“已删除”,为什么会从dbContext中删除跟踪实体?

例如:

var customers = db.Customers
.Where(customer => customer.FirstName.Contains("John"))
.Take(10)
.ToList();

//Let's iterate through the customers -list
//and remove the 5th customer
int i = 1;
foreach(var customer in customers)
{
    if(i == 5)
    {
        //An exception will be thrown
        db.Entry(customer).State = EntityState.Deleted;
    }
    i++;
}
Run Code Online (Sandbox Code Playgroud)

当第5位客户的状态从更改为时UnchangedDeleted整个对象将从上下文甚至是customers-list中销毁。更糟糕的是:这也会引发异常,因为此操作更改了我们正在迭代的列表!

有人可以通过调用将更改保存到数据库之前向我解释为什么会发生这种情况db.SaveChanges()吗?

Sho*_*hoe 5

如果将跟踪实体的状态设置为“已删除”,为什么会从dbContext中删除跟踪实体?

为了防止像这样的事情真的很奇怪...

foreach(var customer in customers)
{
    db.Entry(customer).State = EntityState.Deleted;
}

foreach(var customer in customers)
{
    Console.WriteLine("I'm a deleted customer that still exists");
}
Run Code Online (Sandbox Code Playgroud)

由此产生的后果将迫使我们编写这样的代码。

foreach(var customer in customers)
{
    //Extra code to make sure nothing deleted is in here
    if(db.Entry(customer).State != EntityState.Deleted)
    {
       //Do work
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,对象仍然存在于ObjectStateManager中,但是与对象图的任何正常交互都不会产生任何已删除的对象。您仍然可以看到它像这样存在于其中...

var customer = customers.First();
db.Entry(customer).State = EntityState.Deleted;
Console.WriteLine(db.Entry(customer).State.ToString()); //Deleted
Run Code Online (Sandbox Code Playgroud)

  • Entity Framework 在技术上仍然“标记为删除”;因此该项目仍在 ObjectStateManger 中。然而,dbContext 足够聪明,可以假设如果它被“标记为删除”,你实际上不想再与对象交互。`SaveChanges()` 将实际执行命令以从存储和 ObjectStateManager 中删除项目。 (2认同)