Search code examples
c#.net-coreentity-framework-coreglobal-query-filter

EF Core: Dynamic HasQueryFilter


For a particular use case I need to apply a global query filter for my entities without using generic.

My entities cannot implement any interface, however they have a filed named "CustomFiled". All things I need is apply a filter for CustomFiled property where its value it's not null.

Something like following:

modelBuilder.Entity(entity.ClrType).HasQueryFilter("CustomFiled != null");

Is there any way?


Solution

  • Yes there is, basically it will be a variation of this answer but using a bit more of reflection instead of expression trees. At the end of the OnModelCreating method add something like the following:

    foreach (var mutableEntityType in modelBuilder.Model.GetEntityTypes())
    {
        // check if current entity type has corresponding property 
        var propertyInfo = mutableEntityType.ClrType.GetProperty("CustomFiled");
    
        if (propertyInfo is not null)
        {
            // check it type can be assigned null
            var type = propertyInfo.PropertyType;
            if (type.IsValueType && Nullable.GetUnderlyingType(type) == null)
            {
                continue;
            }
    
            // create filter expression
            var parameter = Expression.Parameter(mutableEntityType.ClrType);
            var body = Expression.NotEqual(
                Expression.Property(parameter, propertyInfo),
                Expression.Constant(null, type));
            var lambdaExpression = Expression.Lambda(body, parameter);
            lambdaExpression.Compile();
    
            // set filter
            mutableEntityType.SetQueryFilter(lambdaExpression);
        }
    }