-
-
Notifications
You must be signed in to change notification settings - Fork 787
Open
Labels
Area: DataIssue is related to filtering, sorting, pagination or projectionsIssue is related to filtering, sorting, pagination or projections🌶️ hot chocolate
Milestone
Description
Is your feature request related to a problem?
Context
If DTO and database entity field has different type, filtering by this field throws error as it's expression is invalid.
For example having this database entity:
public class CharacterEntity
{
public int Id { get; set; }
public string Name { get; set; }
public double Height { get; set; }
public string Status { get; set; }
}
and the corresponding DTO
public class Character
{
public int Id { get; set; }
public string Name { get; set; }
public double Height { get; set; }
public Status Status { get; set; }
}
for field Status
we have different type in database (as String
) and in DTO (as Enum
), accordingly in GraphQL schema we will also gonna have a type Enum for this field.
public enum Status
{
Alive,
Dead,
Unknown
}
Filtering and Projection works just fine as fare client doesn't try to filter by Status
, the generated query expression is going to compare an db.Character.Status(String) == request.Status(Enum)
which obviously is invalid.
query{
characters (
where: {
status: {
eq: ALIVE
}
}
){
nodes {
id
name
height
status
}
}
}
Log output
{
"errors": [
{
"message": "Unexpected Execution Error",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"characters"
],
"extensions": {
"message": "The LINQ expression 'DbSet<CharacterEntity>()\r\n .Where(c => Enum.Parse<Status>(c.Status) == __p_0)' could not be translated. Additional information: Translation of method 'System.Enum.Parse' failed. If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. 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.",
"stackTrace": " at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.<VisitMethodCall>g__CheckTranslated|15_0(ShapedQueryExpression translated, <>c__DisplayClass15_0& )\r\n at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)\r\n at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)\r\n at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)\r\n at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)\r\n at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)\r\n at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)\r\n at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)\r\n at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)\r\n at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)\r\n at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)\r\n at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0()\r\n at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)\r\n at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()\r\n at HotChocolate.Types.Pagination.QueryableCursorPagination`1.ExecuteAsync(IQueryable`1 query, Int32 offset, CancellationToken cancellationToken)\r\n at HotChocolate.Types.Pagination.CursorPaginationAlgorithm`2.ApplyPaginationAsync(TQuery query, CursorPagingArguments arguments, Nullable`1 totalCount, CancellationToken cancellationToken)\r\n at HotChocolate.Types.Pagination.QueryableCursorPagingHandler`1.ResolveAsync(IResolverContext context, IQueryable`1 source, CursorPagingArguments arguments, CancellationToken cancellationToken)\r\n at HotChocolate.Types.Pagination.CursorPagingHandler.HotChocolate.Types.Pagination.IPagingHandler.SliceAsync(IResolverContext context, Object source)\r\n at HotChocolate.Types.Pagination.PagingMiddleware.InvokeAsync(IMiddlewareContext context)\r\n at HotChocolate.Utilities.MiddlewareCompiler`1.ExpressionHelper.AwaitTaskHelper(Task task)\r\n at HotChocolate.Execution.Processing.Tasks.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken)\r\n at HotChocolate.Execution.Processing.Tasks.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken)"
}
}
],
"data": {
"characters": null
}
}
Version
12.13.2
The solution you'd like
It's possible to have something like an field conversion before building the filter expression?
Product
Hot Chocolate
Metadata
Metadata
Assignees
Labels
Area: DataIssue is related to filtering, sorting, pagination or projectionsIssue is related to filtering, sorting, pagination or projections🌶️ hot chocolate