diff --git a/src/HotChocolate/Data/src/Data/Projections/Expressions/QueryableProjectionScopeExtensions.cs b/src/HotChocolate/Data/src/Data/Projections/Expressions/QueryableProjectionScopeExtensions.cs index 3a7eb114a08..421c115e1df 100644 --- a/src/HotChocolate/Data/src/Data/Projections/Expressions/QueryableProjectionScopeExtensions.cs +++ b/src/HotChocolate/Data/src/Data/Projections/Expressions/QueryableProjectionScopeExtensions.cs @@ -35,12 +35,25 @@ public static Expression CreateMemberInit(this QueryableProjectionScope scope) foreach (var val in scope.GetAbstractTypes()) { - var ctor = Expression.New(val.Key); - Expression memberInit = Expression.MemberInit(ctor, val.Value); + var instance = scope.Instance.Peek(); + Expression baseExpression; + if (val.Value.Count == 0) + { + // No field has been selected for this type + // -> Since we need to select something, select all(!) fields + baseExpression = instance; + } + else + { + // One or more fields have been selected for this type + // -> Select only the requested fields. + var ctor = Expression.New(val.Key); + baseExpression = Expression.MemberInit(ctor, val.Value); + } lastValue = Expression.Condition( - Expression.TypeIs(scope.Instance.Peek(), val.Key), - Expression.Convert(memberInit, scope.RuntimeType), + Expression.TypeIs(instance, val.Key), + Expression.Convert(baseExpression, scope.RuntimeType), lastValue); } diff --git a/src/HotChocolate/Data/test/Data.Projections.SqlServer.Tests/QueryableProjectionUnionTypeTests.cs b/src/HotChocolate/Data/test/Data.Projections.SqlServer.Tests/QueryableProjectionUnionTypeTests.cs index 3176bbc40d2..f754a9fc3db 100644 --- a/src/HotChocolate/Data/test/Data.Projections.SqlServer.Tests/QueryableProjectionUnionTypeTests.cs +++ b/src/HotChocolate/Data/test/Data.Projections.SqlServer.Tests/QueryableProjectionUnionTypeTests.cs @@ -214,6 +214,61 @@ await Snapshot .MatchAsync(); } + [Fact] + public async Task Create_Union_Typename_Only() + { + // arrange + var tester = + _cache.CreateSchema(s_barEntities, OnModelCreating, configure: ConfigureSchema); + + // act + var res1 = await tester.ExecuteAsync( + OperationRequestBuilder.New() + .SetDocument( + @" + { + root { + __typename + } + }") + .Build()); + + // assert + await Snapshot + .Create() + .AddResult(res1) + .MatchAsync(); + } + + [Fact] + public async Task Create_Union_Typename_Concrete_Mixed() + { + // arrange + var tester = + _cache.CreateSchema(s_barEntities, OnModelCreating, configure: ConfigureSchema); + + // act + var res1 = await tester.ExecuteAsync( + OperationRequestBuilder.New() + .SetDocument( + @" + { + root { + __typename + ... on Foo { + fooProp + } + } + }") + .Build()); + + // assert + await Snapshot + .Create() + .AddResult(res1) + .MatchAsync(); + } + private static void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity() diff --git a/src/HotChocolate/Data/test/Data.Projections.SqlServer.Tests/__snapshots__/QueryableProjectionUnionTypeTests.Create_Union_Typename_Concrete_Mixed.snap b/src/HotChocolate/Data/test/Data.Projections.SqlServer.Tests/__snapshots__/QueryableProjectionUnionTypeTests.Create_Union_Typename_Concrete_Mixed.snap new file mode 100644 index 00000000000..89f967f23c0 --- /dev/null +++ b/src/HotChocolate/Data/test/Data.Projections.SqlServer.Tests/__snapshots__/QueryableProjectionUnionTypeTests.Create_Union_Typename_Concrete_Mixed.snap @@ -0,0 +1,22 @@ +Result: +--------------- +{ + "data": { + "root": [ + { + "__typename": "Bar" + }, + { + "__typename": "Foo", + "fooProp": "FooProp" + } + ] + } +} +--------------- + +SQL: +--------------- +SELECT "d"."d" = 'bar', "d"."Id", "d"."Name", "d"."d", "d"."BarProp", "d"."FooProp", "d"."d" = 'foo' +FROM "Data" AS "d" +--------------- diff --git a/src/HotChocolate/Data/test/Data.Projections.SqlServer.Tests/__snapshots__/QueryableProjectionUnionTypeTests.Create_Union_Typename_Only.snap b/src/HotChocolate/Data/test/Data.Projections.SqlServer.Tests/__snapshots__/QueryableProjectionUnionTypeTests.Create_Union_Typename_Only.snap new file mode 100644 index 00000000000..241262a8936 --- /dev/null +++ b/src/HotChocolate/Data/test/Data.Projections.SqlServer.Tests/__snapshots__/QueryableProjectionUnionTypeTests.Create_Union_Typename_Only.snap @@ -0,0 +1,21 @@ +Result: +--------------- +{ + "data": { + "root": [ + { + "__typename": "Bar" + }, + { + "__typename": "Foo" + } + ] + } +} +--------------- + +SQL: +--------------- +SELECT "d"."d" = 'bar', "d"."Id", "d"."Name", "d"."d", "d"."BarProp", "d"."FooProp", "d"."d" = 'foo' +FROM "Data" AS "d" +---------------