Filter out all requests (trying to achieve soft deletion)

I am trying to work with soft delete style in EF Core 2.0.

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

Creating the correct column and soft-deleting work fine, but filtering objects from DbContext is not.

I would like to use query filtering in context, but I'm stuck.

 protected override void OnModelCreating(ModelBuilder modelBuilder) { Type entityType; // ^^^ it contains type of entity, eg. Blog, Post, etc. using // modelBuilder.Model.GetEntityTypes().First().Name and converting to Type var entity = modelBuilder.Entity(entityType); if(entityType.GetInterface("ISoftDeleteModel") != null) { // ??? how to access IsDeleted property ??? entity.HasQueryFilter(x => !x.IsDeleted); } } 

The question is simple - how to access the IsDeleted property?

If I knew the type of object, for example. Post and Post implemented by ISoftDeleteModel. I could do this:

 protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Post>().HasQueryFilter(x => !x.IsDeleted); } 

But I do not know the type. I am trying to achieve a simple goal - all models implementing this interface will be automatically filtered. Did I miss something?

+5
source share
1 answer

It is not possible to verify the exact API, but the general approach would be to create a limited general method and call it through reflection:

 public static class EFFilterExtensions { public static void SetSoftDeleteFilter(this ModelBuilder modelBuilder, Type entityType) { SetSoftDeleteFilterMethod.MakeGenericMethod(entityType) .Invoke(null, new object[] { modelBuilder }); } static readonly MethodInfo SetSoftDeleteFilterMethod = typeof(EFFilterExtensions) .GetMethods(BindingFlags.Public | BindingFlags.Static) .Single(t => t.IsGenericMethod && t.Name == "SetSoftDeleteFilter"); public static void SetSoftDeleteFilter<TEntity>(this ModelBuilder modelBuilder) where TEntity : class, ISoftDeleteModel { modelBuilder.Entity<TEntity>().HasQueryFilter(x => !x.IsDeleted); } } 

Now you can use something like this inside OnModelCreating :

 foreach (var type in modelBuilder.Model.GetEntityTypes()) { if (typeof(ISoftDeleteModel).IsAssignableFrom(type.ClrType)) modelBuilder.SetSoftDeleteFilter(type.ClrType); } 
+9
source

Source: https://habr.com/ru/post/1269819/


All Articles