Skip to content

Commit 0de20f6

Browse files
committed
.
1 parent 661fa00 commit 0de20f6

6 files changed

Lines changed: 25 additions & 9 deletions

File tree

src/GraphQL.EntityFramework/GraphApi/EfGraphQLService_Navigation.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public FieldBuilder<TSource, TReturn> AddNavigationField<TSource, TReturn, TProj
8181

8282
// Store projection expression - flows through to Select expression builder
8383
IncludeAppender.SetProjectionMetadata(field, projection, typeof(TSource));
84-
// Also set include metadata as fallback for cases where projection processing doesn't find navigations
84+
// Also set include metadata as fallback for abstract types where projection can't be built
8585
var includeNames = FilterProjectionAnalyzer.ExtractRequiredProperties(projection);
8686
IncludeAppender.SetIncludeMetadata(field, name, includeNames);
8787

@@ -151,7 +151,7 @@ public FieldBuilder<TSource, TReturn> AddNavigationField<TSource, TReturn>(
151151

152152
// Store projection expression - flows through to Select expression builder
153153
IncludeAppender.SetProjectionMetadata(field, projection, typeof(TSource));
154-
// Also set include metadata as fallback
154+
// Also set include metadata as fallback for abstract types where projection can't be built
155155
var includeNames = FilterProjectionAnalyzer.ExtractRequiredProperties(projection);
156156
IncludeAppender.SetIncludeMetadata(field, name, includeNames);
157157

src/GraphQL.EntityFramework/GraphApi/EfGraphQLService_NavigationConnection.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ public ConnectionBuilder<TSource> AddNavigationConnectionField<TSource, TReturn>
131131
}
132132
}
133133

134+
// Use via reflection
135+
// ReSharper disable once UnusedMember.Local
134136
ConnectionBuilder<TSource> AddEnumerableConnection<TSource, TGraph, TReturn>(
135137
ComplexGraphType<TSource> graph,
136138
string name,
@@ -206,6 +208,8 @@ ConnectionBuilder<TSource> AddEnumerableConnection<TSource, TGraph, TReturn>(
206208
return builder;
207209
}
208210

211+
// Use via reflection
212+
// ReSharper disable once UnusedMember.Local
209213
ConnectionBuilder<TSource> AddEnumerableConnectionWithProjection<TSource, TGraph, TReturn, TProjection>(
210214
ComplexGraphType<TSource> graph,
211215
string name,
@@ -219,7 +223,7 @@ ConnectionBuilder<TSource> AddEnumerableConnectionWithProjection<TSource, TGraph
219223

220224
// Store projection expression - flows through to Select expression builder
221225
IncludeAppender.SetProjectionMetadata(builder.FieldType, projection, typeof(TSource));
222-
// Also set include metadata as fallback
226+
// Also set include metadata as fallback for abstract types where projection can't be built
223227
var includeNames = FilterProjectionAnalyzer.ExtractRequiredProperties(projection);
224228
IncludeAppender.SetIncludeMetadata(builder.FieldType, name, includeNames);
225229

@@ -294,6 +298,8 @@ ConnectionBuilder<TSource> AddEnumerableConnectionWithProjection<TSource, TGraph
294298
return builder;
295299
}
296300

301+
// Use via reflection
302+
// ReSharper disable once UnusedMember.Local
297303
ConnectionBuilder<TSource> AddEnumerableConnectionWithProjectionOnly<TSource, TGraph, TReturn>(
298304
ComplexGraphType<TSource> graph,
299305
string name,
@@ -306,10 +312,13 @@ ConnectionBuilder<TSource> AddEnumerableConnectionWithProjectionOnly<TSource, TG
306312

307313
// Store projection expression - flows through to Select expression builder
308314
IncludeAppender.SetProjectionMetadata(builder.FieldType, projection, typeof(TSource));
309-
// Also set include metadata as fallback
315+
// Also set include metadata as fallback for abstract types where projection can't be built
310316
var includeNames = FilterProjectionAnalyzer.ExtractRequiredProperties(projection);
311317
IncludeAppender.SetIncludeMetadata(builder.FieldType, name, includeNames);
312318

319+
// No resolver set - this overload is for interface types where the concrete types provide resolvers
320+
// The projection metadata flows through to the Select expression builder
321+
313322
var hasId = keyNames.ContainsKey(typeof(TReturn));
314323

315324
//TODO: works around https://github.com/graphql-dotnet/graphql-dotnet/pull/2581/
@@ -319,4 +328,4 @@ ConnectionBuilder<TSource> AddEnumerableConnectionWithProjectionOnly<TSource, TG
319328
field.AddWhereArgument(hasId);
320329
return builder;
321330
}
322-
}
331+
}

src/GraphQL.EntityFramework/GraphApi/EfGraphQLService_NavigationList.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public FieldBuilder<TSource, TReturn> AddNavigationListField<TSource, TReturn, T
7171

7272
// Store projection expression - flows through to Select expression builder
7373
IncludeAppender.SetProjectionMetadata(field, projection, typeof(TSource));
74-
// Also set include metadata as fallback
74+
// Also set include metadata as fallback for abstract types where projection can't be built
7575
var includeNames = FilterProjectionAnalyzer.ExtractRequiredProperties(projection);
7676
IncludeAppender.SetIncludeMetadata(field, name, includeNames);
7777

@@ -131,7 +131,7 @@ public FieldBuilder<TSource, TReturn> AddNavigationListField<TSource, TReturn>(
131131

132132
// Store projection expression - flows through to Select expression builder
133133
IncludeAppender.SetProjectionMetadata(field, projection, typeof(TSource));
134-
// Also set include metadata as fallback
134+
// Also set include metadata as fallback for abstract types where projection can't be built
135135
var includeNames = FilterProjectionAnalyzer.ExtractRequiredProperties(projection);
136136
IncludeAppender.SetIncludeMetadata(field, name, includeNames);
137137

src/GraphQL.EntityFramework/GraphApi/EfGraphQLService_QueryableConnection.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ public ConnectionBuilder<TSource> AddQueryConnectionField<TSource, TReturn>(
118118
}
119119
}
120120

121+
// Use via reflection
122+
// ReSharper disable once UnusedMember.Local
121123
ConnectionBuilder<TSource> AddQueryableConnection<TSource, TGraph, TReturn>(
122124
IComplexGraphType graph,
123125
string name,

src/GraphQL.EntityFramework/IncludeAppender.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,15 @@ void ProcessProjectionField(
140140
navigationProperties,
141141
navProjections,
142142
context);
143-
// Only return if we added navigations; otherwise fall through to check field name
143+
// Only return if we added navigations; otherwise fall through to include metadata
144+
// This handles cases like abstract types where projection can't be built
144145
if (navProjections.Count > countBefore)
145146
{
146147
return;
147148
}
148149
}
149150

150-
// Check if this field has include metadata (legacy approach)
151+
// Check if this field has include metadata (fallback for abstract types, or legacy/obsolete approach)
151152
if (TryGetIncludeMetadata(fieldInfo.FieldType, out var includeNames))
152153
{
153154
// It's a navigation field - include ALL navigation properties from metadata

src/GraphQL.EntityFramework/Where/TypeConverter.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ static IList ConvertStringsToListInternal(IEnumerable<string> values, Type type)
104104
static MethodInfo enumListMethod = typeof(TypeConverter)
105105
.GetMethod("GetEnumList", BindingFlags.Static | BindingFlags.NonPublic)!;
106106

107+
// Use via reflection
108+
// ReSharper disable once UnusedMember.Local
107109
static List<T> GetEnumList<T>(IEnumerable<string> values)
108110
where T : struct
109111
{
@@ -119,6 +121,8 @@ static List<T> GetEnumList<T>(IEnumerable<string> values)
119121
static MethodInfo nullableEnumListMethod = typeof(TypeConverter)
120122
.GetMethod("GetNullableEnumList", BindingFlags.Static | BindingFlags.NonPublic)!;
121123

124+
// Use via reflection
125+
// ReSharper disable once UnusedMember.Local
122126
static List<T?> GetNullableEnumList<T>(IEnumerable<string> values)
123127
where T : struct
124128
{

0 commit comments

Comments
 (0)