Closed ghost closed 4 years ago
When using Dynamic Linq, I would expect code like:
var result = context.UserShares.Select("it.GetDisplayName(true, true, true).Contains(\"John\")");
Hey Stef, thanks for the quick answer! I think there is some missing information on our part, we try to execute the query something like this:
var projects = context.Projects;
var filter = "UserShares.Any(User.GetDisplayName(true,true,false).Contains(\"John\"))";
var filtered = projects.Where(filter);
This code should work:
var projects = new[]
{
new { UserShares = new [] { new User { Name = "John" } } }
}.AsQueryable();
var filter = "UserShares.Any(GetDisplayName(true,true,false).Contains(\"John\"))";
var filtered = projects.Where(filter);
See same file for example.
Hey, we ran some tests and could only reproduce this error when using a real database, so not an in-memory one. Using the in-memory db, all the queries we tested completed successfully. We are using the Npgsql.EntityFrameworkCore.PostgreSQL provider.
Looking at the stack trace, we guess that maybe the function is found correctly with the (bool, bool, bool) signature using reflection and then the parameters are inserted as strings, instead of bool, so the error occurrs. But that's just a wild guess.
System.ArgumentException Method 'System.String GetDisplayName(Boolean, Boolean, Boolean)' declared on type SWSF.Model.UserService.BaseUser' cannot be called with instance of type 'System.String'
at System.Linq.Expressions.Expression.ValidateCallInstanceType(Type instanceType, MethodInfo method)
at System.Linq.Expressions.Expression.ValidateStaticOrInstanceMethod(Expression instance, MethodInfo method)
at System.Linq.Expressions.Expression.ValidateMethodAndGetParameters(Expression instance, MethodInfo method)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, Expression arg0, Expression arg1, Expression arg2)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable'1 arguments)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitWhereClause(WhereClause whereClause, QueryModel queryModel, Int32 index)
at Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection'1 bodyClauses, QueryModel queryModel)
at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.VisitSubQuery(SubQueryExpression expression)
at Npgsql.EntityFrameworkCore.PostgreSQL.Query.ExpressionVisitors.NpgsqlSqlTranslatingExpressionVisitor.VisitSubQuery(SubQueryExpression expression)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitWhereClause(WhereClause whereClause, QueryModel queryModel, Int32 index)
at Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection'1 bodyClauses, QueryModel queryModel)
at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.VisitQueryModel(QueryModel queryModel)
at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateQueryExecutor[TResult](QueryModel queryModel)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](Expression query, IQueryModelGenerator queryModelGenerator, IDatabase database, IDiagnosticsLogger'1 logger, Type contextType)
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func'1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Remotion.Linq.QueryableBase'1.GetEnumerator()
at System.Linq.Enumerable.WhereEnumerableIterator'1.ToList()
at System.Linq.Enumerable.ToList[TSource](IEnumerable'1 source)
at SWSF.BusinessObjects.SqlBo'2.FindEntities()
So I looked more into it and couldn't get it to work in a simple console app. I tried again with the PostgreSQL database and logged the expression query. I also tried to get the sql-statement from the query but that threw the above pasted error.
Query string:
Context.Users.Where("UserGroups.Any(User.GetDisplayName(true, true, false).Contains(\"2\"))")
Resulting query expression:
Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[Model.User])
.Where(Param_0 => Param_0.UserGroups.Any(Param_1 => Param_1.User.GetDisplayName(True, True, False).Contains("2"))
For other filtering strings I can get the sql query, but if I try to add the users "GetDisplayName"-function in this particular level of the query, it breaks when I try to retrieve the sql.
Other query:
Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[Model.User])
.Where(Param_0 => Param_0.UserGroups.Any(Param_1 => (Param_1.User.GivenName != null))
Translates to sql:
SELECT u."Id", u."Discriminator", u."Email", u."FamilyName", u."GivenName", u."Nickname"
FROM "Users" AS u
WHERE (u."Discriminator" = 'User') AND EXISTS (
SELECT 1
FROM "UserGroups" AS u0
INNER JOIN "Users" AS "u.User" ON u0."UserId" = "u.User"."Id"
WHERE ("u.User"."Discriminator" IN ('User', 'BaseUser') AND "u.User"."GivenName" IS NOT NULL) AND (u."Id" = u0."UserId"))
So I think that this is a problem of the PostgreSQL provider, what do you think?
Hello @SolidWhiteSven ,
I will close this issue. As you pointed out it looks the problem is with the PostgreSQL provider and not the library.
Best Regards,
Jon
Performance Libraries
context.BulkInsert(list, options => options.BatchSize = 1000);
Entity Framework Extensions • Entity Framework Classic • Bulk Operations • Dapper Plus
Runtime Evaluation
Eval.Execute("x + y", new {x = 1, y = 2}); // return 3
C# Eval Function • SQL Eval Function
Hey, we ran into an error that we couldn’t explain ourselves. We have a User class that contains the method “string GetDisplayName(bool, bool, bool)”. The following query works when querying the Owner, which is of type User, on the Project dataset:
The above query runs as expected. This query below doesn’t however. Here we have an instance of that class shared with a user, where the connection is made through a UserShare object. The query is run on Projects:
The resulting error says :
(tell me, if you need the stack trace)
We use EF Core 2.2.1 and access a PostgreSQL database, if that is of any use.
Any help would be appreciated. It seems like a bug to us, but we could be wrong about that. Thanks in advance and have a nice day :-)