Asked by:
InvalidOperationException: When called from 'VisitLambda', rewriting node of type 'ParameterExpression' must return a non-null value of the same type

Question
-
I am trying to upgrade to Entity Framework Core 3.0 from 2.2 and I am facing the below exception where I have created some expression and applied globally to all the entities as global filter. This expression condition worked fine in old version EF Core 2.2
Codes in DbContext:
modelBuilder.GlobalFilters<FilterColumns>(i => i.TenantId == 1, nameof(FilterColumns.TenantId)); modelBuilder.GlobalFilters<FilterColumns>(i => i.IsActive== true, nameof(FilterColumns.IsActive));
My Custom Class:
public class FilterColumns { public int TenantId {get; set;} public bool IsActive { get; set; } }
My ModelBuilder Extension Method:
public static void GlobalFilters<TClass>(this ModelBuilder modelBuilder, Expression<Func<TClass, bool>> expression, string property) { var body = expression?.Body; var baseType = expression?.GetType().GetGenericArguments().FirstOrDefault()?.GetGenericArguments().FirstOrDefault(); var propertyType = baseType?.GetProperty(property)?.PropertyType; if (body != null) { if (property != null) { var allEntities = modelBuilder?.Model.GetEntityTypes().Where(e => e.FindProperty(property) != null).Select(e => e.ClrType).ToList(); if (allEntities != null) { foreach (var entity in allEntities) { var entityPropertyType = entity?.GetProperty(property)?.PropertyType; if (entityPropertyType == propertyType) { var param = expression?.Parameters.Single().ToString(); var entityParam = Expression.Parameter(entity); var expressionVisitor = new CustomExpressionVisitor(entity, baseType, entityParam); var customExpression = expressionVisitor.Visit(expression?.Body); var lambdaExpression = Expression.Lambda(customExpression, entityParam); var oldExpression = modelBuilder?.Entity(entity).Metadata.GetQueryFilter(); if (oldExpression != null) { lambdaExpression = Expression.Lambda( Expression.AndAlso(Expression.Invoke(lambdaExpression, parameter), Expression.Invoke(oldExpression, parameter)), oldExpression.Parameters.Single()); } modelBuilder?.Entity(entity).HasQueryFilter(lambdaExpression); } } } } } }
CustomExpressionVisitor Class:
public class CustomExpressionVisitor : ExpressionVisitor { private readonly Type entityType; private readonly Type baseEntityType; private readonly ParameterExpression param; public CustomExpressionVisitor(Type entityType, Type baseEntityType, ParameterExpression param) { this.entityType = entityType; this.baseEntityType = baseEntityType; this.param = param; } protected override Expression VisitMember(MemberExpression expression) { if (expression.Member.DeclaringType == this.baseEntityType) { return Expression.PropertyOrField(this.param, expression.Member.Name); } return base.VisitMember(expression); } }
I have expected the result from the table by applying the query filter but when I tried to access data from the table using linq query I am getting the following error. Can you anyone suggest your solution to resolve this error or any other better way to apply entity global filter in EF Core 3.0?
Exception Details:
at System.Linq.Expressions.ExpressionVisitor.VisitAndConvert[T](T node, String callerName) at System.Dynamic.Utils.ExpressionVisitorUtils.VisitParameters(ExpressionVisitor visitor, IParameterProvider nodes, String callerName) at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression`1 node) at System.Linq.Expressions.Expression`1.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at Microsoft.EntityFrameworkCore.Query.ReplacingExpressionVisitor.Visit(Expression expression) at System.Linq.Expressions.ExpressionVisitor.VisitInvocation(InvocationExpression node) at System.Linq.Expressions.InvocationExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at Microsoft.EntityFrameworkCore.Query.ReplacingExpressionVisitor.Visit(Expression expression) at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node) at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at Microsoft.EntityFrameworkCore.Query.ReplacingExpressionVisitor.Visit(Expression expression) at Microsoft.EntityFrameworkCore.Query.ReplacingExpressionVisitor.Replace(Expression original, Expression replacement, Expression tree) at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.ExpandNavigationsInLambdaExpression(NavigationExpansionExpression source, LambdaExpression lambdaExpression) at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.ProcessWhere(NavigationExpansionExpression source, LambdaExpression predicate) at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.ApplyQueryFilter(NavigationExpansionExpression navigationExpansionExpression) at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.VisitConstant(ConstantExpression constantExpression) at System.Linq.Expressions.ConstantExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.ExpandAndReduce(Expression query, Boolean applyInclude) at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.Expand(Expression query) at Microsoft.EntityFrameworkCore.Query.QueryTranslationPreprocessor.Process(Expression query) at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query) at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler) at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.System.Collections.Generic.IEnumerable<TEntity>.GetEnumerator() at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at SampleGlobalEntityFiltersCore3._0.Controllers.HomeController.Privacy() in D:\Git Lab Source\HelpDesk\samples\Sample_Global_Entity_Filters_Core3.0\SampleGlobalEntityFiltersCore3.0\Controllers\HomeController.cs:line 35 at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync() at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
Thanks in advance.Tuesday, October 22, 2019 12:02 PM
All replies
-
Hi,
Here I found a similar issue on GitHub. Maybe it can help you.
https://github.com/aspnet/EntityFrameworkCore/issues/16597
Or you can submit a new issue on GitHub.
Regards,
Kyle
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.Wednesday, October 23, 2019 9:53 AM -
Hi Kyle,
I have already created an issue in GitHub.
Issue Link: https://github.com/aspnet/EntityFrameworkCore/issues/18510
Regards,
Ragunaathan M P
Wednesday, October 23, 2019 10:25 AM