EF Core:如何非泛型为含CustomFiled字段的实体添加全局查询过滤
实现无泛型、无接口的全局查询过滤
可以通过**表达式树(Expression Tree)**构建查询过滤条件,动态生成CustomFiled != null的过滤逻辑,完全避开泛型和实体接口的限制。具体实现步骤如下:
1. 构建动态过滤表达式
创建方法,根据实体类型动态生成过滤Lambda表达式:
private static LambdaExpression CreateCustomFieldFilter(Type entityType) { // 获取实体的CustomFiled属性 var customFieldProp = entityType.GetProperty("CustomFiled"); if (customFieldProp == null) { throw new InvalidOperationException($"实体 {entityType.Name} 未定义CustomFiled属性"); } // 仅处理可空类型(引用类型或可空值类型) bool isNullable = customFieldProp.PropertyType.IsReferenceType || Nullable.GetUnderlyingType(customFieldProp.PropertyType) != null; if (!isNullable) { // 不可空值类型永远不会为null,返回恒真表达式跳过过滤 return Expression.Lambda(Expression.Constant(true), Expression.Parameter(entityType)); } // 构建表达式:x => x.CustomFiled != null var parameter = Expression.Parameter(entityType, "x"); var propertyAccess = Expression.Property(parameter, customFieldProp); var notNullExpr = Expression.NotEqual(propertyAccess, Expression.Constant(null, customFieldProp.PropertyType)); return Expression.Lambda(notNullExpr, parameter); }
2. 在Model构建时批量应用过滤
在DbContext的OnModelCreating方法中,遍历所有实体类型,对包含CustomFiled的实体自动应用全局过滤:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { var clrType = entityType.ClrType; // 检查实体是否包含CustomFiled属性 if (clrType.GetProperty("CustomFiled") != null) { var filterExpr = CreateCustomFieldFilter(clrType); // 应用全局查询过滤 modelBuilder.Entity(clrType).HasQueryFilter(filterExpr); } } }
说明
- 该方案通过反射获取实体属性,结合表达式树动态生成过滤逻辑,完全满足你的需求。
- 加入可空类型检查,避免对不可空值类型(如
int)生成无效的!= null判断。 - 实现效果与你期望的
modelBuilder.Entity(entity.ClrType).HasQueryFilter("CustomFiled != null")一致,且符合EF Core的API规范(HasQueryFilter不接受字符串参数,仅支持Lambda表达式)。
内容的提问来源于stack exchange,提问作者bit
相关产品推荐
相关产品推荐

