我的问题是…
我将询问我的用户,他是否想要删除记录。如果他说是,
我实际上不打算从表中删除行,但会将表的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和代码优先。解决方案需要两个部分。首先,你的每个数据类都必须实现一个接口,它公开了一个"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,这就不适用了。