You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Expressions not working with global query filters #33
Sorry for the confusion. The VS had 6.6.0 as a default version. I updated to 9.0.0 and got this error now:
Message:
System.InvalidOperationException : The LINQ expression 'DbSet<Product>()
.Where(p => p.GetTenantId() == 3)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
Stack Trace:
QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
QueryCompilationContext.CreateQueryExecutorExpression[TResult](Expression query)
QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
Database.CompileQuery[TResult](Expression query, Boolean async)
QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
<>c__DisplayClass11_0`1.<ExecuteCore>b__0()
CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
QueryCompiler.ExecuteCore[TResult](Expression query, Boolean async, CancellationToken cancellationToken)
QueryCompiler.Execute[TResult](Expression query)
EntityQueryProvider.Execute[TResult](Expression expression)
EntityQueryable`1.GetEnumerator()
IEnumerable<TEntity>.GetEnumerator()
List`1.ctor(IEnumerable`1 collection)
Enumerable.ToList[TSource](IEnumerable`1 source)
EntityFilterEfTests.Products_TenantNotSet_Returns_AllProducts() line 161
RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
I finally had time to look into this. I have created a pre-release version that maybe you can test: #35
It only works with one of the two evaluation modes, specifically the LimitedCompatibilityButCached mode (which is the faster one). The problem seems to be the order in which the query compilation decoraters are added. Maybe there is a better way to solve this, but now it seems like I need to get the existing query compiler to wrap my compiler, rather than the other way around (I wrap the existing one) which is how it's been working until now.
I got some time now to try it out.
I'm getting the slightly different error as compared to earlier:
System.InvalidOperationException: 'The LINQ expression 'DbSet<Track>()
.Where(t => t.Album == null ? null : (int?)t.Album.Artist.ArtistId == (int?)100)' could not be translated. Additional information: Translation of member 'Album' on entity type 'Track' failed. This commonly occurs when the specified member is unmapped.
Translation of member 'Album' on entity type 'Track' failed. This commonly occurs when the specified member is unmapped. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'
It almost seems that because of expressionify it is unable to follow associations as the error complains it is unable to work with Track.Album property. That property is defined like this:
I actually found Expressionify library through the Projectables project as I wanted to try out all possible options and assess which one would be most fit for my requirements.
I'm not versed in either library's internals, so I apologize if this reference is irrelevant. But maybe there is something to be looked into in that library that could help this implementation as well.
I wish I had the time to look into it properly, unfortunately I don't and I'm on holiday right now. Projectables seems to have sorted it some other way, according to the commit history. That way might be implementable here as well, but I don't have the equipment to try it out while on holiday.
Activity
mariusGundersen commentedon Feb 24, 2025
Seems like this is the method not implemented https://github.com/dotnet/efcore/blob/e2a5f01d041d97630f4852371a6614497f69bdb1/src/EFCore/Query/Internal/IQueryCompiler.cs#L61
mariusGundersen commentedon Feb 24, 2025
Hang on, which version of expressionify are you using? It looks like v6, but you need v9
Seramis commentedon Feb 24, 2025
I used the latest available from nuget.org at the time when i made this post. (about 3 days ago)
EDIT: Wait. VS has installed 6.6.0. For some reason, latest version was not the default option. I'll retest!
Seramis commentedon Feb 24, 2025
Sorry for the confusion. The VS had 6.6.0 as a default version. I updated to 9.0.0 and got this error now:
mariusGundersen commentedon Mar 21, 2025
I finally had time to look into this. I have created a pre-release version that maybe you can test: #35
It only works with one of the two evaluation modes, specifically the
LimitedCompatibilityButCachedmode (which is the faster one). The problem seems to be the order in which the query compilation decoraters are added. Maybe there is a better way to solve this, but now it seems like I need to get the existing query compiler to wrap my compiler, rather than the other way around (I wrap the existing one) which is how it's been working until now.Seramis commentedon Jul 16, 2025
Hi @mariusGundersen,
Sorry for delayed answer.
How could I access the pre-release version to try it out? (As nupkg or dll file for example? Or some pre-release version in nuget repository?)
Thanks!
mariusGundersen commentedon Jul 16, 2025
Just search for pre releases when doing the nuget install, or pick the version explicitly: https://www.nuget.org/packages/Clave.Expressionify/9.2.0-global-query-filter.70
Seramis commentedon Jul 18, 2025
Thank you!
I got some time now to try it out.
I'm getting the slightly different error as compared to earlier:
I currently have a test-setup with the widely distributed example database "Chinook" in SQLite: https://github.com/lerocha/chinook-database
Nuget's involved are:
I tried to add
GetArtistId()onTrackentity and define a fixed global filter based on that.I made the following changes:
My DbContext (I use scaffolding, so there are some partial methods and other such thing involved):
For
Trackentity made the extension class:And then making a query. It fails to translate the query.
When I don't use Expressionify's capabilities and define the global filter as below (identical to the expression above), it works:
It almost seems that because of expressionify it is unable to follow associations as the error complains it is unable to work with
Track.Albumproperty. That property is defined like this:... and
OnModelCreatingin DB context is like this:I hope I didn't miss anything. Let me know if I can provide any additional information.
EDIT:
I also noticed that even simple
.Where()clause has broken with 9.2.0-global-query-filter.70, while it works properly with 9.1.0. Example query:mariusGundersen commentedon Jul 19, 2025
Then I'm afraid it might not be possible to implement so it works in global query filters 😕
Seramis commentedon Jul 19, 2025
That is unfortunate.
Just for background information, EntityFrameworkCore.Projectables can do that if a certain one-liner is included based on this: EFNext/EntityFrameworkCore.Projectables#81 (And when a new version is released, it will be done automatically by the library.)
I actually found Expressionify library through the Projectables project as I wanted to try out all possible options and assess which one would be most fit for my requirements.
I'm not versed in either library's internals, so I apologize if this reference is irrelevant. But maybe there is something to be looked into in that library that could help this implementation as well.
mariusGundersen commentedon Jul 19, 2025
I wish I had the time to look into it properly, unfortunately I don't and I'm on holiday right now. Projectables seems to have sorted it some other way, according to the commit history. That way might be implementable here as well, but I don't have the equipment to try it out while on holiday.
Seramis commentedon Jul 19, 2025
Completely understandable.
Please, enjoy your holiday. :)