0


Ef Core花里胡哨系列(1) SafeDelete、ReadOnly、Audit 安全删除、只读、审计等

Ef Core花里胡哨系列(1) SafeDelete、ReadOnly、Audit 安全删除、只读、审计等

在软件设计中,软删除是一种常见的数据管理技术,用于标记和隐藏被删除的数据,而不是永久地从数据库中删除它们。软删除通常通过在数据表中添加一个额外的标志列(例如"IsDeleted")来实现。当数据被删除时,该标志列被设置为指示删除状态的值(通常是true或1),而不是直接从数据库中删除数据记录。

使用软删除的主要原因是保留数据的完整性和可追溯性。通过软删除,我们可以避免永久删除数据,从而避免意外或不可逆的数据丢失。软删除还可以帮助我们满足法律、合规性或审计要求,因为我们可以跟踪和记录数据的删除历史。

另一个重要的原因是软删除可以提供更好的用户体验。软删除允许用户恢复被删除的数据,而不必联系管理员或支持团队。这对于误删除或需要恢复数据的情况非常有用。

然而,软删除也有一些潜在的缺点。首先,软删除会增加数据库的存储需求,因为被删除的数据仍然存在于数据库中。其次,软删除可能会导致查询和性能方面的复杂性,因为我们需要在查询中过滤掉已删除的数据。

总之,软删除是一种在软件设计中常见的数据管理技术,它通过标记和隐藏被删除的数据来保留数据的完整性和可追溯性。它提供了更好的用户体验,并满足法律和合规性要求。然而,软删除也有一些潜在的缺点,需要在设计和实现时加以考虑。

定义约束

我们先定义一个安全删除的接口,用于约束对应的实体类。

publicinterfaceISoftDelete{publicbool IsDeleted{get;set;}}

通过重写ef core来实现对实现了该接口的成员进行自动处理

通过读取

ef core

上下文中追踪的实体,如果是继承自

ISoftDelete

接口,说明便不是直接删除数据,而是软删除即更新数据,将实体对应的

IsDeleted

标记更改为

true

,随后将状态改为

EntityState.Modified

即进行更新操作。

publicclassSampleDbContext(DbContextOptions<SampleDbContext> options,IServiceProvider serviceProvider):DbContext(options){publicoverrideasyncTask<int>SaveChangesAsync(CancellationToken cancellationToken =newCancellationToken()){foreach(var entityEntry in ChangeTracker.Entries<IEntity>()){if(entityEntry is{ Entity:ISafeDelete safeDelete,State: EntityState.Deleted }){
                safeDelete.IsDeleted =true;
                entityEntry.State = EntityState.Modified;}}returnawaitbase.SaveChangesAsync(cancellationToken);}}

如何查询时自动过滤?

我们通过重写

OnModelCreating

方法,来预置一些

Ef Core

的行为,例如

HasQueryFilter

来预置一个过滤条件,如果是继承自

ISoftDelete

的实体,那便需要过滤掉已经软删除的数据。

HasQueryFilter

仅可以配置一种过滤,且每次查询都会生效。如果有权限相关的管理,建议在仓储层通过权限来实现过滤,更灵活一些或者可以通过在lambda中使用

IgnoreQueryFilters()

来忽略过滤,例如:

DbSet<TEntity>().IgnoreQueryFilters()

publicclassSampleDbContext(DbContextOptions<SampleDbContext> options,IServiceProvider serviceProvider):DbContext(options){protectedoverridevoidOnModelCreating(ModelBuilder modelBuilder){foreach(var entityType in modelBuilder.Model.GetEntityTypes()){if(typeof(ISafeDelete).IsAssignableFrom(entityType.ClrType)){
                modelBuilder.Entity(entityType.ClrType).HasQueryFilter(GetFilterExpression(entityType.ClrType));}}base.OnModelCreating(modelBuilder);}privateExpression<Func<IEntity,bool>>GetFilterExpression(Type type){var parameter = Expression.Parameter(type,"e");var property = Expression.Property(parameter,nameof(ISafeDelete.IsDeleted));var body = Expression.Equal(property, Expression.Constant(false));return Expression.Lambda<Func<IEntity,bool>>(body, parameter);}publicoverrideasyncTask<int>SaveChangesAsync(CancellationToken cancellationToken =newCancellationToken()){foreach(var entityEntry in ChangeTracker.Entries<IEntity>()){if(entityEntry is{ Entity:ISafeDelete safeDelete,State: EntityState.Deleted }){
                safeDelete.IsDeleted =true;
                entityEntry.State = EntityState.Modified;}}returnawaitbase.SaveChangesAsync(cancellationToken);}}

联想扩展

我们通过

ISoftDelete

约束实现了软删除,那么我们可以实现其它什么操作呢?

我们可以实现一些基于逻辑的业务操作,例如只读,或者是审计信息等等。

只读

ReadOnly

在软件设计中,我们一些表可能是记录型数据,是不允许更改的,不能简单的从接口上约束操作,我们可以实现一个

IReadOnly

接口来标记对应的实体。

publicinterfaceIReadOnly{}
publicclassSampleDbContext(DbContextOptions<SampleDbContext> options,IServiceProvider serviceProvider):DbContext(options){publicoverrideasyncTask<int>SaveChangesAsync(CancellationToken cancellationToken =newCancellationToken()){foreach(var entityEntry in ChangeTracker.Entries<IEntity>()){// 模式匹配语法,即实体如果继承自 IReadOnly 接口且上下文的状态不是添加或者是无操作,即抛出异常,不允许该操作if(entityEntry is{ Entity: IReadOnly,State:not(EntityState.Added and EntityState.Unchanged)}){thrownewNotSupportedException();}}returnawaitbase.SaveChangesAsync(cancellationToken);}}
标签: .netcore c# ef core

本文转载自: https://blog.csdn.net/cc1998414/article/details/135337685
版权归原作者 胖纸不争 所有, 如有侵权,请联系我们删除。

“Ef Core花里胡哨系列(1) SafeDelete、ReadOnly、Audit 安全删除、只读、审计等”的评论:

还没有评论