I have a simple very basic API implementation. It returns the data perfectly when using the HotChocolate interface.
However, I want to join data and return it as such when the consumer calls to the endpoint.
When I execute on a projected model, the query sent to the database has a different name than my properties in my model - I cannot find a resource to explain to me why.
Model is absolutely massive, with more than 300 properties, so I am going to just add 2 properties with the IQueryable
I am attempting to nest with the response.
This is FlatTable.cs
:
public int ID { get; set; }
public string? UniqueValue { get; set; }
[UseSorting]
public ICollection<ClientAPRole>? IMUK_PAF_ClientAPRoles { get; set; }
This is ClientAPRole.cs
:
public int ID { get; set; }
public string? UniqueValue { get; set; }
public string? Status { get; set; }
My simple dbcontext
:
public class FormsAssistDbContext : DbContext
{
public FormsAssistDbContext(DbContextOptions options)
: base(options)
{
}
public DbSet<FlatTable> IMUK_PAF_FlatTable => Set<FlatTable>();
public DbSet<ClientAPRole> IMUK_PAF_ClientAPRoles => Set<ClientAPRole>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<FlatTable>()
.OwnsMany(f => f.IMUK_PAF_ClientAPRoles);
base.OnModelCreating(modelBuilder);
}
}
And finally my Query.cs
:
public class Query
{
[UsePaging]
[UseProjection]
[UseFiltering]
public IQueryable<FlatTable?> GetFlatTables(FormsAssistDbContext context)
=> context.IMUK_PAF_FlatTable;
}
From all the guides and resources I've gathered that this should just work.
However, when running this GraphQL query:
query GetFlatTables{
flatTables{
id
uniqueValue
imuk_PAF_ClientAPRoles{
id
status
uniqueValue
}
}
}
I sometimes get invalid object and sometimes invalid column name from the result (when I don't add the APRoles
to the dbcontext
):
{
"errors": [
{
"message": "Unexpected Execution Error",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"flatTables"
],
"extensions": {
"message": "Invalid object name 'ClientAPRole'.",
"stackTrace": /.. removed for brevity
}
}
]
}
When I add the APRoles
to the dbcontext
:
{
"errors": [
{
"message": "Unexpected Execution Error",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"flatTables"
],
"extensions": {
"message": "Invalid column name 'FlatTableID'.\r\nInvalid column name 'FlatTableID'.\r\nInvalid column name 'FlatTableID'.",
"stackTrace": " at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__208_0(Task`1 result)\r\n at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()\r\n at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj)\r\n at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n--- End of stack trace from previous location ---\r\n at System.Threading.ExecutionContext.RunInternal(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 Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)\r\n at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)\r\n at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()\r\n at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)\r\n at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)\r\n at HotChocolate.Data.ToListMiddleware`1.InvokeAsync(IMiddlewareContext context)\r\n at HotChocolate.Resolvers.Expressions.Parameters.ServiceHelper.<>c__DisplayClass7_3`1.<<UseResolverServiceInternal>b__5>d.MoveNext()\r\n--- End of stack trace from previous location ---\r\n at HotChocolate.Resolvers.Expressions.Parameters.ServiceHelper.<>c__DisplayClass7_1`1.<<UseResolverServiceInternal>b__3>d.MoveNext()\r\n--- End of stack trace from previous location ---\r\n at HotChocolate.Execution.Processing.Tasks.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken)\r\n at HotChocolate.Execution.Processing.Tasks.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken)"
}
}
]
}
It makes the target column MyClass + Column for some reason - I don't know why this behavior is happening based off my code.
I watched a bunch of youtube videos and guides, did some reading up on the main website, tried changing my query to, tried using linq for the join explicitly, and now consulting stackoverflow.