question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Runtime Exception when passing Func<Entity, bool> into Filtered Include

See original GitHub issue

Ask a question

Hey there. I am posting as a question, because I am not sure whether or not this is a bug.

We have multiple Data Models that have BeginAt and InactiveAt properties. These are used to handle the case of soft deletes. The business rule we use is as follows:

var activeAt = DateTime.Now;
isActive = x.BeginAt <= activeAt && (x.InactiveAt == null || x.InactiveAt > activeAt)

Since we use this for multiple of our entities, we were hoping to store it as a Func to result in less duplicated logic. Here is what we have come up with:

public static Func<TEntity, bool> FilterActiveAtFunction<TEntity>(DateTime activeAt) where TEntity : class, IDataRecordEntity
{
      return new Func<TEntity, bool>(x => x.BeginAt <= activeAt && (x.InactiveAt == null || x.InactiveAt > activeAt));
}

I am trying to use this function as follows for our :

var activeAt = DateTime.Now;
return  this.GetAll()
                .AsQueryable()
                .Include(u => u.Users.Where(DataRecordExpressions.FilterActiveAtFunction<Users>(activeAt)))
                .ToList();

That throws the following exception:

System.ArgumentException: Expression of type 'System.Func`2[Wildsparq.Models.Users.UserTeam,System.Boolean]' cannot be used for parameter of type 'System.Linq.Expressions.Expression`1[System.Func`2[Wildsparq.Models.Users.UserTeam,System.Boolean]]' of method 'System.Linq.IQueryable`1[Wildsparq.Models.Users.UserTeam] Where[UserTeam](System.Linq.IQueryable`1[Wildsparq.Models.Users.UserTeam], System.Linq.Expressions.Expression`1[System.Func`2[Wildsparq.Models.Users.UserTeam,System.Boolean]])' (Parameter 'arg1')
   at System.Dynamic.Utils.ExpressionUtils.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arguments, ParameterInfo pi, String methodParamName, String argumentParamName, Int32 index)
   at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression arg0, Expression arg1)
   at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable`1 arguments)
   at System.Linq.Expressions.Expression.Call(MethodInfo method, IEnumerable`1 arguments)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryableMethodNormalizingExpressionVisitor.TryConvertEnumerableToQueryable(MethodCallExpression methodCallExpression)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryableMethodNormalizingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   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 System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
   at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryableMethodNormalizingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryableMethodNormalizingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryableMethodNormalizingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryableMethodNormalizingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryableMethodNormalizingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryableMethodNormalizingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryableMethodNormalizingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryTranslationPreprocessor.NormalizeQueryableMethod(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryTranslationPreprocessor.NormalizeQueryableMethod(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.QueryTranslationPreprocessor.Process(Expression query)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryTranslationPreprocessor.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.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 System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Wildsparq.Api.Controllers.UserIdentityController.GetAllowedUsersForIdentity() in C:\Users\Jacob Justice\Documents\dev\wildsparq\Wildsparq.Api\Controllers\UserIdentityController.cs:line 68

Note, if I hardcode the same logic, as follows, everything works:

var activeAt = DateTime.Now;
return  this.GetAll()
                .AsQueryable()
                .Include(u => u.Users.Where(x => x.BeginAt <= activeAt && (x.InactiveAt == null || x.InactiveAt > activeAt)))
                .ToList();

Is this just not supported for filtered include yet?

Include provider and version information

EF Core version: 5.0.8 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: .NET 5.0 Operating system: Windows 10 IDE: Rider

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
rojicommented, Aug 27, 2021

@jacobhjustice note that you should be able to achieve what you want via a method returning an Expression<Func<...>>, which is an expression tree that EF Core can see and translate, rather than a Func<...>, which represents compiled runnable .NET code which is opaque to EF:

public static Expression<Func<TEntity, bool>> FilterActiveAtFunction<TEntity>(DateTime activeAt)
    where TEntity : class, IDataRecordEntity
    => x => x.BeginAt <= activeAt && (x.InactiveAt == null || x.InactiveAt > activeAt);

var activeAt = DateTime.Now;
_ = ctx.Blogs
    .Include(u => u.Users.AsQueryable().Where(BlogContext.FilterActiveAtFunction<User>(activeAt)))
    .ToList();

Note that AsQueryable is needed inside your Include to select the IQueryable version of Where.

0reactions
jacobhjusticecommented, Aug 27, 2021

No I have not. Good chance it was running in memory.

We decided our work around is going to be to create a view of our datatable that specifically only has active records, that will help us to avoid duplicating the logic (at least for this entity) in multiple places.

It would definitely be helpful to have the error be a little more clear (maybe doing so will help someone in the future). Spend half the day trying to figure out the issue 🤮 Didn’t realize I would get such a quick answer here or I would have asked sooner. Thanks for all you do to contribute! @smitpatel

Read more comments on GitHub >

github_iconTop Results From Across the Web

Subquery.Where(Expression<Func<Entity, bool>>) throws ...
I have subquery that is generating that same error, but only when the Func is passed into the method containing the query. System....
Read more >
Filtering on Include in EF Core
Filtered Include has given rise to some confusion on how it affects filtering a query as a whole. The rule of the thumb...
Read more >
Use user-filtered exception handlers
The runtime tests the specific exception first. If the specific exception succeeds, the runtime executes the user filter. The generic filter ...
Read more >
transcribestreamingservice - Amazon Web Services - Go SDK
Amazon Transcribe streaming offers three main types of real-time transcription: Standard, Medical, and Call Analytics. Standard transcriptions are the most ...
Read more >
comprehend - Amazon Web Services - Go SDK
Error for service API and SDK errors. Use runtime type assertions with awserr.Error's Code and Message methods to get detailed information about the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found