实体框架将保存更改覆盖到软删除实体 [英] Entity framework override save changes to soft delete entities

查看:42
本文介绍了实体框架将保存更改覆盖到软删除实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在数据库上下文"中覆盖Savechanges,以将我的实体标记为SoftDeleted.

I am trying to override Savechanges in My Database Context to mark my entites as SoftDeleted.

我有一个ISoftDeletable基础,可以在我的实体类中覆盖它

I have an ISoftDeletable base which i override in my Entity classes

public interface IsoftDeletable
{
    public bool IsDeleted {get; set;}
}

然后在我的上下文中

public override int SaveChanges()
{
    foreach (var entry in ChangeTracker.Entries()
              .Where(p => p.State == EntityState.Deleted))
        SoftDelete(entry);

    return base.SaveChanges();
}

private void SoftDelete(DbEntityEntry entry)
{
   var entity = entry.Entity as ISoftDeltable;
   entity.IsDeleted = true;
   entry.State = EntityState.Modified;
}

如果我删除一个实体,上面的示例可以正常工作,但是它被软删除了,但问题是,如果该实体具有带有Cascade删除功能的子集合,则这些子集合不会被实体框架跟踪,也不会被标记为已删除.

The above example works ok if i delete an Entity it gets soft deleted but the problem is that if that entity has Child Collections with Cascade delete, the child collections are not tracked by the Entity Framework and they are not marked as deleted.

一个简单的解决方案是在删除发生之前急切地加载将要删除的实体的所有子集合,因此Ef也会跟踪子项中的更改并对其进行软删除,但这是一个黑客"想要避免.很难记住实体之间的所有关系,并在删除发生之前就急于加载所有内容.此外,如果模型发生更改,将很难维持这一点.

One simple solution was to eagerly load all of the child Collections of the Entity that is going to be deleted before the delete happens so the Ef tracks the changes in the children too and soft delete them but this is a "hack" i want to avoid. It will be hard to remember all the relations between entities and eager load everything just before the delete happens. Also it will be hard to maintain this if the model changes.

有没有更好的方法来实现这种功能?

Is there any better way to achieve that funcionallity?

我看不到这个问题如何复制

Edit 1: I dont see how this question might be dublicate of this

推荐答案

我会尝试在DBMS方面而不是在应用程序方面进行尝试.

I would try something on the DBMS side, not on the application side.

我将假设您具有MS SQL Server.MS SQL Server支持级联更新"的方式与级联删除"的方式类似.这意味着,如果您有一个具有主键PersonID的Person表和一个Car表,其中在Person表中有一个引用PersonID的PersonID外键,则每当您更改PersonID中Person的值时,相关记录中的外键汽车也将使用此值进行更新.

I'm gonna assume that you have MS SQL Server. MS SQL Server supports "on cascade update" in a similar fashion as "on cascade delete". It means that if you have an Person table with primary key PersonID and a Car table where there is a PersonID foreign key referencing the PersonID in the Person table, whenever you change the value in Person for PersonID, the foreign key in the related record in Car is also updated with this value.

因此,在您的情况下,我将要做的是修改外键.假设您有两个表:

So in your case what I would do is modify the foreign keys. Let's say you have two tables:

人员:(PersonId,姓名,年龄,IsDeleted)
汽车:(CarId,品牌,型号,PersonId,IsDeleted)

Person: (PersonId, Name, Age, IsDeleted)
Car: (CarId, Make, Model, PersonId, IsDeleted)

PersonID是Person中的PK,而CarId是Car中的PK.而不是使Car.PersonId成为引用Person.PersonId的FK,而是创建一个复合外键:(Car.PersonId,Car.IsDeleted)=>(Person.PersonId,Person.IsDeleted)然后指定更新级联"复合FK的选件.这样,每当您更改Person.PersonId(永远不会)或Person.IsDeleted时,新值将被级联更新为相应的Car.PersonId(再次,由于Person.PersonId不会更改,因此不会级联更新),并且Car.IsDeleted.

PersonID is the PK in Person, and CarId is the PK in Car. And instead of making Car.PersonId a FK referencing Person.PersonId, you create a composite foreign key: (Car.PersonId, Car.IsDeleted) => (Person.PersonId, Person.IsDeleted) AND you specify the "on update cascade" option for this composite FK. This way whenever you change Person.PersonId (which you never will) or Person.IsDeleted, the new values will be cascade updated into the corresponding Car.PersonId (which again, will not be cascade updated because Person.PersonId will not change) and Car.IsDeleted.

这篇关于实体框架将保存更改覆盖到软删除实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆