实体框架5.0中的虚拟删除

本文关键字:虚拟 删除 框架 实体 | 更新日期: 2023-09-27 17:49:55

我的问题是…

我将询问我的用户,他是否想要删除记录。如果他说是,

我实际上不打算从表中删除行,但会将表的Deleted列更新为true。但在此之前,我想检查外键约束,就像我们在删除行情况下做的那样,意味着如果值被其他表使用。我应该告诉用户这行被其他表使用了,不能删除?

你知道我该怎么做吗?

当前我这样做是为了删除…

public bool Delete(dynamic entity)
{
    try
    {
        //here I want to check, whether this is being used by some other table or not. Foreign key constaint
        entity.Deleted = true;
        this.SaveChanges();
        return true;
    }
    catch { return false; }
}

实体框架5.0中的虚拟删除

我的答案适用于实体框架5.0和代码优先。解决方案需要两个部分。首先,你的每个数据类都必须实现一个接口,它公开了一个"Deleted"属性(我们称之为IVirtualDelete)。

public interface IVirtualDelete{
  bool Deleted {get; set;}
}

第二,您需要在DBContext中重写SaveChanges方法。

当SaveChanges被调用时,查看context.ChangeTracker.Entities()中那些有System.Data.EntityState.Deleted状态的,并且这个实体实现了你的IVirtualDelete接口。在该对象上设置"已删除",并将实体状态修改为"已修改"。

public override int SaveChanges() {
  foreach (var item in this.ChangeTracker.Entries().Where(x=> x.EntityState == EntityState.Deleted)){
    var entity = item.Entity as IVirtualDelete;
    if(entity != null){
      entity.Deleted = true;
      item.EntityState = EntityState.Modified;
    }
  }
  return base.SaveChanges();
}

就是这样。EF没有方法将删除重写为更新,最后可能会认为这并不好,因为机制可能会变化(删除的时间戳等)。你所做的就是People在这里所做的

您可以尝试更改实体的主键值并保存。

如果存在子记录,您将收到某种级联更新错误并返回false。

如果更新成功-您没有子记录,您可以将主键值更改回原始值,设置Deleted = true并重新保存

当然,如果你的主键是identity,或者子表是'delete cascade' user-visible-scenario,这就不适用了。