Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interceptor for IQueryable<TEntity> just before it is converted to expression #35510

Closed
SpaceOgre opened this issue Jan 22, 2025 · 6 comments
Closed

Comments

@SpaceOgre
Copy link

What problem are you trying to solve?

I would like to have one place to do custom logic to the IQueryable just before EF Core compiles it to an expression.

For instance I'm using the LinqKit library to use dynamic expressions in selects etc, this requires me to use add a AsExpanded() call to all my queries.

Describe the solution you'd like

I would like to be able to use an interceptor, like a IQueryExpressionInterceptor but for IQueryable.
So something like this:

public class ExpandingQueryableInterceptor
{
    public IQueryable<T> QueryCompilationStarting<T>(IQueryable<T> query)
        => query.AsExpandable();
}
@roji
Copy link
Member

roji commented Jan 22, 2025

Are you looking for this?

@SpaceOgre
Copy link
Author

No, at least I don't think so. I need to work on the IQueryable specifically and not on the Expression.

@roji
Copy link
Member

roji commented Jan 22, 2025

That unfortunately doesn't really fit with how IQueryable actually works. When you call e.g. ToList() on an IQueryable, that calls the GetEnumerator() method on that IQueryable (EntityQueryable in the EF case), just like ToList() does for anything else. This calls into EF's query pipeline, passing the expression tree in (code). This is the last point where there's an actual IQueryable, and it's too early for EF to support an interceptor; there may be some way to twist the design to make something like this work, but it would be quite complicated and would slow absolutely everyone down, so I don't see doing this just so that you can avoid explicitly specifying AsExpandable() in your queries.

However, unless I'm mistaken, Linqkit also exposes an expression tree visitor which probably does the same thing - and is the thing that's actually done by AsExpandable(). You should be able to use that from the expression tree interceptor I referenced above.

@roji
Copy link
Member

roji commented Jan 22, 2025

I'm going to go ahead and close this as given the current information I don't see us doing it, but feel free to post back if you have other insights/arguments - we can reopen and revisit.

@roji roji closed this as not planned Won't fix, can't repro, duplicate, stale Jan 22, 2025
@SpaceOgre
Copy link
Author

That is totally fair, just a question about IQueryExpressionInterceptor and when it is called. Is it correct that it is called after EF have done some changes to the Expression?

I'm trying to use the Linqkit expression visitor here but it is not working as it should, if I call the visitor on the expression without ef it works.

If this is the case I would like an interceptor for expressions that is called before ef does anything with the expression, so a pre-processor.

And thank you for the time you take to awnser my questions 😊

@roji
Copy link
Member

roji commented Jan 22, 2025

There's a little bit of processing happening before this interceptor is invoked, yes - but only very little (this is mainly because we want the interceptor to happen after query caching, as opposed to super early, on each query execution). But I wouldn't assume that's a problem - give it a try and see if it meets your needs or not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants