ChilliCream / ChilliCream/graphql-platform
Projections don't work for Marten nested objects
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 5.8k
- Forks
- 810
- Avg merge
- 15h 39m
- Merged PRs (30d)
- 98
Description
Product
Hot Chocolate
Version
15.1.12
Link to minimal reproduction
https://github.com/stef-bulteel/HCMartenBug
Steps to reproduce
Run the project
Test both queries in README.md
What is expected?
It is expected Projections "just work" per https://chillicream.com/docs/hotchocolate/v15/integrations/marten#projections
What is actually happening?
An error is thrown as soon as nested data is trying to be queried.
No actual query is launched against postgres.
Relevant log output
{
"errors": [
{
"message": "Unexpected Execution Error",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"products"
],
"extensions": {
"message": "Value cannot be null. (Parameter 'key')",
"stackTrace": " at System.Collections.Generic.Dictionary`2.set_Item(TKey key, TValue value)\r\n at Marten.Linq.Parsing.SelectParser.VisitConstant(ConstantExpression node) in /_/src/Marten/Linq/Parsing/SelectParser.cs:line 79\r\n at Marten.Linq.Parsing.SelectParser.Visit(Expression node) in /_/src/Marten/Linq/Parsing/SelectParser.cs:line 34\r\n at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)\r\n at Marten.Linq.Parsing.SelectParser.VisitBinary(BinaryExpression node) in /_/src/Marten/Linq/Parsing/SelectParser.cs:line 66\r\n at Marten.Linq.Parsing.SelectParser.Visit(Expression node) in /_/src/Marten/Linq/Parsing/SelectParser.cs:line 34\r\n at System.Linq.Expressions.ExpressionVisitor.VisitConditional(ConditionalExpression node)\r\n at Marten.Linq.Parsing.SelectParser.Visit(Expression node) in /_/src/Marten/Linq/Parsing/SelectParser.cs:line 34\r\n at Marten.Linq.Parsing.SelectParser.ReadBinding(MemberAssignment binding) in /_/src/Marten/Linq/Parsing/SelectParser.cs:line 116\r\n at Marten.Linq.Parsing.SelectParser.VisitMemberInit(MemberInitExpression node) in /_/src/Marten/Linq/Parsing/SelectParser.cs:line 96\r\n at Marten.Linq.Parsing.SelectParser.Visit(Expression node) in /_/src/Marten/Linq/Parsing/SelectParser.cs:line 34\r\n at Marten.Linq.Parsing.SelectParser..ctor(ISerializer serializer, IQueryableMemberCollection members, Expression expression) in /_/src/Marten/Linq/Parsing/SelectParser.cs:line 27\r\n at Marten.Linq.Parsing.SelectorVisitor.ToSelectTransform(Expression selectExpression, ISerializer serializer) in /_/src/Marten/Linq/Parsing/SelectorVisitor.cs:line 119\r\n at Marten.Linq.Parsing.SelectorVisitor.VisitMemberInit(MemberInitExpression node) in /_/src/Marten/Linq/Parsing/SelectorVisitor.cs:line 78\r\n at Marten.Linq.Parsing.SelectorVisitor.Visit(Expression node) in /_/src/Marten/Linq/Parsing/SelectorVisitor.cs:line 28\r\n at Marten.Linq.CollectionUsage.BuildTopStatement(IMartenSession session, IQueryableMemberCollection collection, IDocumentStorage storage, QueryStatistics statistics) in /_/src/Marten/Linq/CollectionUsage.Compilation.cs:line 74\r\n at Marten.Linq.Parsing.LinqQueryParser.BuildStatements() in /_/src/Marten/Linq/Parsing/LinqQueryParser.Statements.cs:line 33\r\n at Marten.Linq.Parsing.LinqQueryParser.BuildHandler[TResult]() in /_/src/Marten/Linq/Parsing/LinqQueryParser.Handlers.cs:line 58\r\n at Marten.Linq.MartenLinqQueryProvider.Execute[TResult](Expression expression) in /_/src/Marten/Linq/MartenLinqQueryProvider.cs:line 56\r\n at Marten.Linq.MartenLinqQueryable`1.GetEnumerator() in /_/src/Marten/Linq/MartenLinqQueryable.cs:line 136\r\n at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)\r\n at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)\r\n at HotChocolate.DefaultQueryableExecutable`1.<ToAsyncEnumerable>b__19_0()\r\n at System.Threading.Tasks.Task`1.InnerInvoke()\r\n at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)\r\n--- End of stack trace from previous location ---\r\n at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)\r\n at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)\r\n--- End of stack trace from previous location ---\r\n at HotChocolate.DefaultQueryableExecutable`1.ToAsyncEnumerable(CancellationToken cancellationToken)+MoveNext()\r\n at HotChocolate.DefaultQueryableExecutable`1.ToAsyncEnumerable(CancellationToken cancellationToken)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()\r\n at HotChocolate.Types.Pagination.QueryableCursorPagingHandler`1.QueryExecutor.QueryAsync(IQueryable`1 slicedQuery, IQueryable`1 originalQuery, Int32 offset, Boolean includeTotalCount, CancellationToken cancellationToken)\r\n at HotChocolate.Types.Pagination.QueryableCursorPagingHandler`1.QueryExecutor.QueryAsync(IQueryable`1 slicedQuery, IQueryable`1 originalQuery, Int32 offset, Boolean includeTotalCount, CancellationToken cancellationToken)\r\n at HotChocolate.Types.Pagination.CursorPagingHandler`2.SliceAsync(IResolverContext context, TQuery originalQuery, CursorPagingArguments arguments, CursorPaginationAlgorithm`2 algorithm, ICursorPaginationQueryExecutor`2 executor, CancellationToken cancellationToken)\r\n at HotChocolate.Types.Pagination.QueryableCursorPagingHandler`1.SliceAsyncInternal(IResolverContext context, IQueryableExecutable`1 source, CursorPagingArguments arguments)\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.Execution.Processing.Tasks.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken)\r\n at HotChocolate.Execution.Processing.Tasks.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken)"
}
}
],
"data": {
"products": null
}
}
Additional context
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked minimal reproduction and run both queries described in its README. Trace the nested projection failure from the stack trace through the Marten SelectParser and Hot Chocolate projection execution, then verify that nested queries complete without the null-key error and that PostgreSQL receives the expected query.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, postgres
- Domain
- backend-api-design, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100