过滤所有查询(尝试实现软删除) [英] Filter all queries (trying to achieve soft delete)
问题描述
我正在尝试在 EF Core 2.0 中使用软删除行为.
I am trying to get to work soft delete behaviour in EF Core 2.0.
public interface ISoftDeleteModel
{
bool IsDeleted { get; set; }
}
创建适当的列和软删除工作正常,但从 DbContext 过滤实体不是.
Creating proper column and soft-deleting are working fine but filtering entities from DbContext isn't.
我想在上下文中使用查询过滤,但我卡住了.
I would like to use query filtering in context but I am 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);
}
}
问题很简单 - 如何访问 IsDeleted 属性?
The question is simple - how to access IsDeleted property?
如果我知道实体的类型,例如.发布和发布实现 ISoftDeleteModel 我将能够做到这一点:
If I knew type of the entity, eg. Post, and Post implemented ISoftDeleteModel I would be able to 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 simple thing - all models implementing this interface would be automatically filtered. Am I missing something?
推荐答案
无法测试确切的 API,但一般的方法是创建一个受约束的泛型方法并通过反射调用它:
Can't test the exact API, but the general approach would be to create a constrained generic method and call it via 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);
}
}
现在你可以在你的 OnModelCreating
中使用类似的东西:
Now you can use something like this inside your OnModelCreating
:
foreach (var type in modelBuilder.Model.GetEntityTypes())
{
if (typeof(ISoftDeleteModel).IsAssignableFrom(type.ClrType))
modelBuilder.SetSoftDeleteFilter(type.ClrType);
}
这篇关于过滤所有查询(尝试实现软删除)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!