Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
inline fragments now conditionally return correct field if on the rig…
…ht type and default value on other types
  • Loading branch information
bzbetty committed Jun 14, 2022
commit fbfd874257ee57d67e695437dd53a617814e82e0
35 changes: 25 additions & 10 deletions src/EntityGraphQL/Compiler/EntityGraphQLQueryWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ protected override void VisitField(FieldNode node, IGraphQLNode? context)
throw new EntityGraphQLCompilerException("context should not be null visiting field");
if (context.NextFieldContext == null)
throw new EntityGraphQLCompilerException("context.NextFieldContext should not be null visiting field");

var schemaType = schemaProvider.GetSchemaType(context.NextFieldContext.Type, requestContext);
var actualField = schemaType.GetField(node.Name.Value, requestContext);

Expand Down Expand Up @@ -354,22 +354,37 @@ protected override void VisitFragmentDefinition(FragmentDefinitionNode node, IGr

protected override void VisitInlineFragment(InlineFragmentNode node, IGraphQLNode? context)
{
IGraphQLNode? newContext = context;
if (context == null)
throw new EntityGraphQLCompilerException("context should not be null visiting inline fragment");

if (node.TypeCondition is not null)
if (node.TypeCondition is not null && context is not null)
{
var type = schemaProvider.GetSchemaType(node.TypeCondition.Name.Value, requestContext);
if (type != null)
{
//animals = animals.Select(a => a is Dog ? new { a.name, a.hasBone } : new { a.name }

{
var fragParameter = Expression.Parameter(type.TypeDotnet, $"frag_{type.Name}");
newContext = new GraphQLListSelectionField((GraphQLListSelectionField)context!, fragParameter);
var newContext = new GraphQLListSelectionField((GraphQLListSelectionField)context!, fragParameter);
base.VisitInlineFragment(node, newContext);

//copy the fragment fields over to the select context and cast the type so we can access the property
foreach (var queryField in newContext.QueryFields)
{
var resolveExpression = Expression.Condition(
test: Expression.TypeIs(context.NextFieldContext, type.TypeDotnet),
ifTrue: Expression.Property(Expression.Convert(context.NextFieldContext, type.TypeDotnet), queryField.Name),
ifFalse: Expression.Default(queryField.NextFieldContext?.Type)
);

var fieldResult = new GraphQLScalarField(schemaProvider, queryField.Field, queryField.Name, resolveExpression!, queryField.NextFieldContext as ParameterExpression ?? context.RootParameter, context, queryField.Arguments as Dictionary<string, object>);
context.AddField(fieldResult);
}
}
else
{
base.VisitInlineFragment(node, context);
}
}

base.VisitInlineFragment(node, newContext);
}
}

protected override void VisitFragmentSpread(FragmentSpreadNode node, IGraphQLNode? context)
{
Expand Down
2 changes: 1 addition & 1 deletion src/EntityGraphQL/Compiler/GqlNodes/BaseGraphQLField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public abstract class BaseGraphQLField : IGraphQLNode
public string Name { get; }
public IField? Field { get; }
public List<BaseGraphQLField> QueryFields { get; } = new();
public Expression? NextFieldContext { get; set; }
public Expression? NextFieldContext { get; }
public IGraphQLNode? ParentNode { get; }
public ParameterExpression? RootParameter { get; set; }
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace EntityGraphQL.Compiler
/// </summary>
public abstract class ExecutableGraphQLStatement : IGraphQLNode
{
public Expression? NextFieldContext { get; set; }
public Expression? NextFieldContext { get; }
public IGraphQLNode? ParentNode { get; }
public ParameterExpression? RootParameter { get; }
/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/EntityGraphQL/Compiler/GqlNodes/GraphQLDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace EntityGraphQL.Compiler
/// </summary>
public class GraphQLDocument : IGraphQLNode
{
public Expression? NextFieldContext { get; set; }
public Expression? NextFieldContext { get; }
public IGraphQLNode? ParentNode { get; }
public ParameterExpression? RootParameter { get; }
public List<BaseGraphQLField> QueryFields { get; } = new List<BaseGraphQLField>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace EntityGraphQL.Compiler
{
public class GraphQLFragmentStatement : IGraphQLNode
{
public Expression? NextFieldContext { get; set; }
public Expression? NextFieldContext { get; }
public IGraphQLNode? ParentNode { get; }
public ParameterExpression? RootParameter { get; }

Expand Down
2 changes: 1 addition & 1 deletion src/EntityGraphQL/Compiler/GqlNodes/IGraphQLNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace EntityGraphQL.Compiler
public interface IGraphQLNode
{
string Name { get; }
Expression? NextFieldContext { get; set; }
Expression? NextFieldContext { get; }
IGraphQLNode? ParentNode { get; }
ParameterExpression? RootParameter { get; }

Expand Down
5 changes: 3 additions & 2 deletions src/tests/EntityGraphQL.Tests/QueryTests/QueryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using EntityGraphQL.Tests.ApiVersion1;
using Microsoft.CSharp.RuntimeBinder;
using Microsoft.EntityFrameworkCore;

namespace EntityGraphQL.Tests
{
Expand Down Expand Up @@ -356,7 +357,6 @@ public void TestInheritance()
name
}
}");

var context = new TestAbstractDataContext();
context.Animals.Add(new Dog() { Name = "steve", HasBone = true });
context.Animals.Add(new Cat() { Name = "george", Lives = 9 });
Expand Down Expand Up @@ -398,13 +398,14 @@ ...on Dog {
// we only have the fields requested
Assert.Equal(2, animals.Count);


Assert.Equal("Dog", animals[0].__typename);
Assert.Equal("steve", animals[0].name);
Assert.True(animals[0].hasBone);
Assert.Equal("Cat", animals[1].__typename);
Assert.Equal("george", animals[1].name);
Assert.Equal(9, animals[1].lives);
}


}
}
1 change: 1 addition & 0 deletions src/tests/EntityGraphQL.Tests/TestAbstractDataContext.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System;
using Microsoft.EntityFrameworkCore;

namespace EntityGraphQL.Tests
{
Expand Down