Skip to content

Commit

Permalink
fix(Selection): fix nullable relation (#1651)
Browse files Browse the repository at this point in the history
  • Loading branch information
PascalSenn authored Apr 6, 2020
1 parent 6d4f771 commit e2e8957
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 4 deletions.
48 changes: 48 additions & 0 deletions src/Core/Types.Selection.Abstractions.Tests/SelectionTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,50 @@ public virtual void Execute_Selection_ObjectDeep()
});
}

[Fact]
public virtual void Execute_Selection_ObjectDeepNull()
{
// arrange
IServiceCollection services;
Func<IResolverContext, IEnumerable<Foo>> resolver;
(services, resolver) = _provider.CreateResolver(SAMPLE);

IQueryable<Foo> resultCtx = null;
ISchema schema = SchemaBuilder.New()
.AddServices(services.BuildServiceProvider())
.AddQueryType<Query>(
d => d.Field(t => t.Foos)
.Resolver(resolver)
.Use(next => async ctx =>
{
await next(ctx).ConfigureAwait(false);
resultCtx = ctx.Result as IQueryable<Foo>;
})
.UseSelection())
.Create();
IQueryExecutor executor = schema.MakeExecutable();

// act
executor.Execute(
"{ foos { nestedNull { nestedNull { nestedNull { nestedNull { bar } } } } } }");

// assert
Assert.NotNull(resultCtx);
Assert.Collection(resultCtx.ToArray(),
x =>
{
Assert.Null(x.Bar);
Assert.Equal(0, x.Baz);
Assert.Null(x.Nested);
},
x =>
{
Assert.Null(x.Bar);
Assert.Equal(0, x.Baz);
Assert.Null(x.Nested);
});
}

[Fact]
public virtual void Execute_Selection_ArrayDeep()
{
Expand Down Expand Up @@ -1457,6 +1501,8 @@ public class Foo

public NestedFoo Nested { get; set; }

public NestedFoo NestedNull { get; set; }

public NestedFoo[] ObjectArray { get; set; }

public List<NestedFoo> ObjectList { get; set; }
Expand Down Expand Up @@ -1602,6 +1648,8 @@ public class NestedFoo

public int Baz { get; set; }

public NestedFoo NestedNull { get; set; }

public NestedFoo Nested { get; set; }

public List<NestedFoo> ObjectArray { get; set; }
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Types.Selection/SelectionClosure.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public SelectionClosure(Type clrType, string parameterName)

public Dictionary<string, MemberAssignment> Projections { get; }

public Expression CreateMemberInit()
public MemberInitExpression CreateMemberInit()
{
NewExpression ctor = Expression.New(ClrType);
return Expression.MemberInit(ctor, Projections.Values);
Expand Down
16 changes: 13 additions & 3 deletions src/Core/Types.Selection/SelectionVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,22 @@ protected override void LeaveLeaf(IFieldSelection selection)

protected override void LeaveObject(IFieldSelection selection)
{
if (selection.Field.Member is PropertyInfo)
if (selection.Field.Member is PropertyInfo member)
{
Expression memberInit = Closures.Pop().CreateMemberInit();
SelectionClosure closure = Closures.Pop();

MemberInitExpression memberInit = closure.CreateMemberInit();

MemberExpression property = Expression.Property(
Closures.Peek().Instance.Peek(), member);

Expression withNullCheck = Expression.Condition(
Expression.Equal(property, Expression.Constant(null)),
Expression.Default(memberInit.Type),
memberInit);

Closures.Peek().Projections[selection.Field.Name] =
Expression.Bind(selection.Field.Member, memberInit);
Expression.Bind(selection.Field.Member, withNullCheck);

base.LeaveObject(selection);
}
Expand Down

0 comments on commit e2e8957

Please sign in to comment.