Adding UseProjection to Graphql Query Fails with Unexpected Execution Error in Linq Execution
I am new to Graphql and wanted to try it in an API written in c#.
I am using HotChocolate, EFCore 8, dotnet 8.
I have the following Classes
public class Batch
{
public Batch()
{
}
public Batch(string batchId, string tenantId, int paymentsCount, decimal totalAmount, string status,
string statusDescription)
{
BatchId = batchId;
TenantId = tenantId;
PaymentsCount = paymentsCount;
TotalAmount = totalAmount;
Status = status;
StatusDescription = statusDescription;
}
public string BatchId { get; set; }
public string TenantId { get; set; }
public int PaymentsCount { get; set; }
public decimal TotalAmount { get; set; }
public string Status { get; set; }
public string StatusDescription { get; set; }
[UseFiltering]
[UseSorting]
public ICollection<Payment> Payments { get; set; }
}
public class Payment
{
public Payment()
{
}
public string Id { get; set; }
public string PayeeName { get; set; }
public string CheckNumber { get; set; }
//public List<string> InvoiceNumbers { get; set; }
public DateTime PaymentDate { get; set; }
public string Status { get; set; }
public string StatusDescription { get; set; }
public decimal Amount { get; set; }
}
This is the Grapql Query
public class BatchesQuery
{
// Resolver
[UsePaging(IncludeTotalCount = true)]
[UseProjection]
[UseFiltering]
[UseSorting]
public IQueryable<Batch> Batches([Service] PaymentDbContext paymentDbContext, string tenantId, IResolverContext context)
{
var paymentBatchesQueryable = paymentDbContext.PaymentBatches
.Where(pb => pb.TenantId == tenantId)
.OrderByDescending(pb => pb.CreatedTimestamp)
.AsNoTracking();
var paymentRequests = paymentBatchesQueryable.SelectMany(pb => pb.PaymentRequests);
var payments = paymentRequests.Select(pr => new Payment()
{
Id = pr.PaymentRequestExternalId,
PayeeName = pr.Payee.Name,
CheckNumber = pr.Number,
//InvoiceNumbers = pr.RemittanceDetails.Select(rd => rd.Number).ToList(),
PaymentDate = pr.RequestDate,
Status = pr.PaymentRequestStatusType.ToString(),
StatusDescription = pr.PaymentRequestStatusType.ToString(),
Amount = pr.RemittanceDetails.Sum(rd => rd.Net)
});
var paymentBatches = paymentBatchesQueryable
.Select(pb => new Batch(pb.PaymentBatchExternalId,
pb.TenantId,
pb.PaymentRequests.Count,
pb.PaymentRequests
.SelectMany(pr => pr.RemittanceDetails)
.Sum(rd => rd.Net),
pb.PaymentBatchStatusType.ToString(),
pb.PaymentBatchStatusType.ToString())
{
Payments = payments.ToList()
});
return paymentBatches;
}
}
This is my Setup in Program.cs
builder.Services.AddGraphQLServer()
.AddQueryType<BatchesQuery>()
.AddProjections()
.AddFiltering()
.AddSorting()
.RegisterDbContext<PaymentDbContext>();
I get the following error when I run this query:
query{
batches(tenantId: "yKYrJLSUrE6XDWkrQC0e"){
nodes{
batchId
payments{
id
}
}
}
}
Response:
{
"errors": [
{
"message": "Unexpected Execution Error",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"batches"
],
"extensions": {
"message": "The LINQ expression 'p1 => new Payment{ Id = p1.Id }\r\n' 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.",
"stackTrace": " at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitLambda[T](Expression`1 lambdaExpression)\r\n at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)\r\n at Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)\r\n at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)\r\n at Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerSqlTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)\r\n at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateInternal(Expression expression, Boolean applyDefaultTypeMapping)\r\n at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateProjection(Expression expression, Boolean applyDefaultTypeMapping)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberAssignment(MemberAssignment memberAssignment)\r\n at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.VisitMemberInit(MemberInitExpression memberInitExpression)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Visit(Expression expression)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.RelationalProjectionBindingExpressionVisitor.Translate(SelectExpression selectExpression, Expression expression)\r\n at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateSelect(ShapedQueryExpression source, LambdaExpression selector)\r\n at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)\r\n at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)\r\n at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)\r\n at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)\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": {
"batches": null
}
}
I tried doing the recommendations provided in the response but none of them worked. This error goes away when I remove UseProjections annotation.
I am not sure what's happening. Could someone please explain ?
Comments
Post a Comment