I want to include the
isDeleted values in the database to my index when the user is an admin. I used the global query filter to filter the data.
This is the code I have:
var param = Expression.Parameter(entity.ClrType); var propertyMethodInfo = typeof(EF).GetMethod("Property").MakeGenericMethod(typeof(bool)); var isDeleted = Expression.Call(propertyMethodInfo, param, Expression.Constant("IsDeleted")); BinaryExpression compareExpression = Expression.MakeBinary(ExpressionType.Equal, isDeleted, Expression.Constant(false)); var lambdaExpression = Expression.Lambda(compareExpression, param); builder.Entity(entity.ClrType).HasQueryFilter(lambdaExpression);
The solution is to add additional criteria to your global query filter and make sure it's evaluated dynamically. The technique is basically explained in the Global Query Filters example:
Note the use of a DbContext instance level field: _tenantId used to set the current tenant. Model-level filters will use the value from the correct context instance. I.e. The instance that is executing the query.
The essential part is to use instance field/property/method of your
DbContext, otherwise the filter will not be dynamic.
Following that, add a field to your
bool includeDeleted = false;
and modify you code to produce
p => this.includeDeleted || p.IsDeleted == false:
// ... var includeDeleted = Expression.Field(Expression.Constant(this), "includeDeleted"); var condition = Expression.OrElse(includeDeleted, compareExpression); var lambdaExpression = Expression.Lambda(condition, param); builder.Entity(entity.ClrType).HasQueryFilter(lambdaExpression);
How you populate that field is up to you. It could be via constructor parameter / injection, public property etc.