efcore: Latest builds incompatible with some PostgreSQL array scenarios
When syncing EFCore.PG to latest preview9, some array scenarios are now breaking.
Exception:
Processing of the LINQ expression 'AsQueryable<int>(NavigationTreeExpression
Value: EntityReferenceSomeArrayEntity
Expression: (Unhandled parameter: s).SomeArray)' by 'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core. See https://go.microsoft.com/fwlink/?linkid=2101433 for more detailed information.
at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) in /home/roji/projects/EFCore/src/EFCore/Query/Internal/NavigationExpandingExpressionVisitor.cs:line 573
Query:
var count = ctx.SomeEntities.Count(e => e.SomeArray.Any());
Expression tree before NavigationExpandingExpressionVisitor:
value(Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[Npgsql.EntityFrameworkCore.PostgreSQL.Query.ArrayQueryTest+SomeArrayEntity]).Count(e => e.SomeArray.AsQueryable().Any())
Basically NavigationExpandingExpressionVisitor freaks out when it sees a queryable method (AsQueryable) on an array.
/cc @smitpatel
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 3
- Comments: 20 (12 by maintainers)
Commits related to this issue
- Fix ef core on preview8 until https://github.com/aspnet/EntityFrameworkCore/issues/17374 is fixed — committed to BioWareRu/BioEngine.BRC.Common by SonicGD 5 years ago
- Fix ef core on preview8 until https://github.com/aspnet/EntityFrameworkCore/issues/17374 is fixed — committed to BioWareRu/BioEngine.Core by SonicGD 5 years ago
- Query: Removing Queryable conversion for sources which are not queryable Our EnumerableToQueryable converter works on all the methods. But during nav expansion, we actually inject query sources. If i... — committed to dotnet/efcore by smitpatel 5 years ago
- Query: Removing Queryable conversion for sources which are not queryable Our EnumerableToQueryable converter works on all the methods. But during nav expansion, we actually inject query sources. If i... — committed to dotnet/efcore by smitpatel 5 years ago
- Query: Removing Queryable conversion for sources which are not queryable Our EnumerableToQueryable converter works on all the methods. But during nav expansion, we actually inject query sources. If i... — committed to dotnet/efcore by smitpatel 5 years ago
- Query: Removing Queryable conversion for sources which are not queryable Our EnumerableToQueryable converter works on all the methods. But during nav expansion, we actually inject query sources. If i... — committed to dotnet/efcore by smitpatel 5 years ago
@thepra yes, the important point is that this is the same behavior as in 2.x, but the inefficiency was being hidden by client evaluation - it is now much easier to understand what’s going on.
If I’m reading your code correctly,
allUsersIds
is an array parameter. You can’t join a table with an array, but it seems like the main point of the query is to filter out rows whose ID isn’t in the array. If that’s the case, the query can simply be rewritten as follows:Unfortunately Contains on an array currently doesn’t work (that’s what this issue is about), but this is planned to be fixed for 3.1.0.
Another more extreme option is to use the
unnest
PostgreSQL function to expand the array to a table-like set of rows, and join on that:EF Core will not generate this kind of advanced, PostgreSQL-specific SQL, and most probably never will. However, you can use raw SQL to write it yourself and have EF materialize the results back to entity instances.
好大一个坑,好惨
This is true and we’re aware of the one-time porting pain that disabling client evaluation may cause. We do believe it’s the better way for EF Core to function, as it makes perf issues much more visible and improves compatibility across versions.
You should be able to use Join, but you must use it on entity types rather than on array parameters as you tried above.
@thepra - join with client side array is not supported since that join has to be client eval. It has no correlation with PostgreSQL arrays.
Yes. We have many queries like
and they are failing with
Well, it prevents translation of several array operations, including inside JSON documents (the new feature). Specifically, this prevents translating Any and Contains.
It would definitely be a shame to not have this - but I guess it’s not completely critical if this goes into 3.1 instead?