Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion docs/defining-graphs.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public class OrderGraph :
Field<StringGraphType>("customerName")
.ResolveAsync(async context =>
{
var data = base.ResolveDbContext(context);
var data = ResolveDbContext(context);
// CustomerId is available even though it wasn't in the GraphQL query
var customer = await data.Customers
.Where(c => c.Id == context.Source.CustomerId)
Expand Down
2 changes: 1 addition & 1 deletion docs/filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Notes:
<!-- snippet: FiltersSignature -->
<a id='snippet-FiltersSignature'></a>
```cs
public partial class Filters<TDbContext>
public class Filters<TDbContext>
where TDbContext : DbContext
{
public delegate bool Filter<in TEntity>(object userContext, TDbContext data, ClaimsPrincipal? userPrincipal, TEntity input);
Expand Down
2 changes: 1 addition & 1 deletion src/GraphQL.EntityFramework/Filters/Filters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ namespace GraphQL.EntityFramework;

#region FiltersSignature

public partial class Filters<TDbContext>
public class Filters<TDbContext>
where TDbContext : DbContext
{
public delegate bool Filter<in TEntity>(object userContext, TDbContext data, ClaimsPrincipal? userPrincipal, TEntity input);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,64 +3,6 @@
partial class EfGraphQLService<TDbContext>
where TDbContext : DbContext
{
[Obsolete("Use the projection-based overload instead")]
public FieldBuilder<TSource, TReturn> AddNavigationField<TSource, TReturn>(
ComplexGraphType<TSource> graph,
string name,
Func<ResolveEfFieldContext<TDbContext, TSource>, TReturn?>? resolve = null,
Type? graphType = null,
IEnumerable<string>? includeNames = null)
where TReturn : class
{
Ensure.NotWhiteSpace(nameof(name), name);

graphType ??= GraphTypeFinder.FindGraphType<TReturn>();

var field = new FieldType
{
Name = name,
Type = graphType
};
IncludeAppender.SetIncludeMetadata(field, name, includeNames);

if (resolve is not null)
{
field.Resolver = new FuncFieldResolver<TSource, TReturn?>(
async context =>
{
var fieldContext = BuildContext(context);

TReturn? result;
try
{
result = resolve(fieldContext);
}
catch (Exception exception)
{
throw new(
$"""
Failed to execute navigation resolve for field `{name}`
GraphType: {graphType.FullName}
TSource: {typeof(TSource).FullName}
TReturn: {typeof(TReturn).FullName}
""",
exception);
}

if (fieldContext.Filters == null ||
await fieldContext.Filters.ShouldInclude(context.UserContext, fieldContext.DbContext, context.User, result))
{
return result;
}

return null;
});
}

graph.AddField(field);
return new FieldBuilderEx<TSource, TReturn>(field);
}

public FieldBuilder<TSource, TReturn> AddNavigationField<TSource, TReturn, TProjection>(
ComplexGraphType<TSource> graph,
string name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,12 @@
partial class EfGraphQLService<TDbContext>
where TDbContext : DbContext
{
static MethodInfo addEnumerableConnection = typeof(EfGraphQLService<TDbContext>)
.GetMethod("AddEnumerableConnection", BindingFlags.Instance | BindingFlags.NonPublic)!;

static MethodInfo addEnumerableConnectionWithProjection = typeof(EfGraphQLService<TDbContext>)
.GetMethod("AddEnumerableConnectionWithProjection", BindingFlags.Instance | BindingFlags.NonPublic)!;

static MethodInfo addEnumerableConnectionWithProjectionOnly = typeof(EfGraphQLService<TDbContext>)
.GetMethod("AddEnumerableConnectionWithProjectionOnly", BindingFlags.Instance | BindingFlags.NonPublic)!;

[Obsolete("Use the projection-based overload instead")]
public ConnectionBuilder<TSource> AddNavigationConnectionField<TSource, TReturn>(
ComplexGraphType<TSource> graph,
string name,
Func<ResolveEfFieldContext<TDbContext, TSource>, IEnumerable<TReturn>>? resolve = null,
Type? itemGraphType = null,
IEnumerable<string>? includeNames = null,
bool omitQueryArguments = false)
where TReturn : class
{
Ensure.NotWhiteSpace(nameof(name), name);

itemGraphType ??= GraphTypeFinder.FindGraphType<TReturn>();

var addConnectionT = addEnumerableConnection.MakeGenericMethod(typeof(TSource), itemGraphType, typeof(TReturn));

try
{
var arguments = new object?[]
{
graph,
name,
resolve,
includeNames,
omitQueryArguments
};
return (ConnectionBuilder<TSource>) addConnectionT.Invoke(this, arguments)!;
}
catch (Exception exception)
{
throw new(
$"""
Failed to execute navigation connection for field `{name}`
ItemGraphType: {itemGraphType.FullName}
TSource: {typeof(TSource).FullName}
TReturn: {typeof(TReturn).FullName}
""",
exception);
}
}

public ConnectionBuilder<TSource> AddNavigationConnectionField<TSource, TReturn, TProjection>(
ComplexGraphType<TSource> graph,
string name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,6 @@
partial class EfGraphQLService<TDbContext>
where TDbContext : DbContext
{
[Obsolete("Use the projection-based overload instead")]
public FieldBuilder<TSource, TReturn> AddNavigationListField<TSource, TReturn>(
ComplexGraphType<TSource> graph,
string name,
Func<ResolveEfFieldContext<TDbContext, TSource>, IEnumerable<TReturn>>? resolve = null,
Type? itemGraphType = null,
IEnumerable<string>? includeNames = null,
bool omitQueryArguments = false)
where TReturn : class
{
Ensure.NotWhiteSpace(nameof(name), name);

var hasId = keyNames.ContainsKey(typeof(TReturn));
var field = new FieldType
{
Name = name,
Type = MakeListGraphType<TReturn>(itemGraphType),
Arguments = ArgumentAppender.GetQueryArguments(hasId, true, false),
};
IncludeAppender.SetIncludeMetadata(field, name, includeNames);

if (resolve is not null)
{
field.Resolver = new FuncFieldResolver<TSource, IEnumerable<TReturn>>(async context =>
{
var fieldContext = BuildContext(context);
var result = resolve(fieldContext);

if (result is IQueryable)
{
throw new("This API expects the resolver to return a IEnumerable, not an IQueryable. Instead use AddQueryField.");
}

result = result.ApplyGraphQlArguments(hasId, context, omitQueryArguments);
if (fieldContext.Filters == null)
{
return result;
}

return await fieldContext.Filters.ApplyFilter(result, context.UserContext, fieldContext.DbContext, context.User);
});
}

graph.AddField(field);
return new FieldBuilderEx<TSource, TReturn>(field);
}

public FieldBuilder<TSource, TReturn> AddNavigationListField<TSource, TReturn, TProjection>(
ComplexGraphType<TSource> graph,
string name,
Expand Down
26 changes: 0 additions & 26 deletions src/GraphQL.EntityFramework/GraphApi/EfInterfaceGraphType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,20 @@ public EfInterfaceGraphType(IEfGraphQLService<TDbContext> graphQlService):this(g

public IEfGraphQLService<TDbContext> GraphQlService { get; } = graphQlService;

[Obsolete("Use the projection-based overload instead")]
public ConnectionBuilder<TSource> AddNavigationConnectionField<TReturn>(
string name,
Type? graphType = null,
IEnumerable<string>? includeNames = null,
bool omitQueryArguments = false)
where TReturn : class =>
GraphQlService.AddNavigationConnectionField<TSource, TReturn>(this, name, null, graphType, includeNames, omitQueryArguments);

public ConnectionBuilder<TSource> AddNavigationConnectionField<TReturn>(
string name,
Expression<Func<TSource, IEnumerable<TReturn>?>> projection,
Type? graphType = null)
where TReturn : class =>
GraphQlService.AddNavigationConnectionField(this, name, projection, graphType);

[Obsolete("Use the projection-based overload instead")]
public FieldBuilder<TSource, TReturn> AddNavigationField<TReturn>(
string name,
Type? graphType = null,
IEnumerable<string>? includeNames = null)
where TReturn : class =>
GraphQlService.AddNavigationField<TSource, TReturn>(this, name, null, graphType, includeNames);

public FieldBuilder<TSource, TReturn> AddNavigationField<TReturn>(
string name,
Expression<Func<TSource, TReturn?>> projection,
Type? graphType = null)
where TReturn : class =>
GraphQlService.AddNavigationField(this, name, projection, graphType);

[Obsolete("Use the projection-based overload instead")]
public FieldBuilder<TSource, TReturn> AddNavigationListField<TReturn>(
string name,
Type? graphType = null,
IEnumerable<string>? includeNames = null,
bool omitQueryArguments = false)
where TReturn : class =>
GraphQlService.AddNavigationListField<TSource, TReturn>(this, name, null, graphType, includeNames, omitQueryArguments);

public FieldBuilder<TSource, TReturn> AddNavigationListField<TReturn>(
string name,
Expression<Func<TSource, IEnumerable<TReturn>?>> projection,
Expand Down
29 changes: 0 additions & 29 deletions src/GraphQL.EntityFramework/GraphApi/EfObjectGraphType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,6 @@ public class EfObjectGraphType<TDbContext, TSource>(IEfGraphQLService<TDbContext
public void AutoMap(IReadOnlyList<string>? exclusions = null) =>
Mapper<TDbContext>.AutoMap(this, GraphQlService, exclusions);

[Obsolete("Use the projection-based overload instead")]
public ConnectionBuilder<TSource> AddNavigationConnectionField<TReturn>(
string name,
Func<ResolveEfFieldContext<TDbContext, TSource>, IEnumerable<TReturn>>? resolve = null,
Type? graphType = null,
IEnumerable<string>? includeNames = null,
bool omitQueryArguments = false)
where TReturn : class =>
GraphQlService.AddNavigationConnectionField(this, name, resolve, graphType, includeNames, omitQueryArguments);

public ConnectionBuilder<TSource> AddNavigationConnectionField<TReturn, TProjection>(
string name,
Expression<Func<TSource, TProjection>> projection,
Expand All @@ -43,15 +33,6 @@ public ConnectionBuilder<TSource> AddNavigationConnectionField<TReturn>(
where TReturn : class =>
GraphQlService.AddNavigationConnectionField(this, name, projection, graphType);

[Obsolete("Use the projection-based overload instead")]
public FieldBuilder<TSource, TReturn> AddNavigationField<TReturn>(
string name,
Func<ResolveEfFieldContext<TDbContext, TSource>, TReturn?>? resolve = null,
Type? graphType = null,
IEnumerable<string>? includeNames = null)
where TReturn : class =>
GraphQlService.AddNavigationField(this, name, resolve, graphType, includeNames);

public FieldBuilder<TSource, TReturn> AddNavigationField<TReturn, TProjection>(
string name,
Expression<Func<TSource, TProjection>> projection,
Expand All @@ -67,16 +48,6 @@ public FieldBuilder<TSource, TReturn> AddNavigationField<TReturn>(
where TReturn : class =>
GraphQlService.AddNavigationField(this, name, projection, graphType);

[Obsolete("Use the projection-based overload instead")]
public FieldBuilder<TSource, TReturn> AddNavigationListField<TReturn>(
string name,
Func<ResolveEfFieldContext<TDbContext, TSource>, IEnumerable<TReturn>>? resolve = null,
Type? graphType = null,
IEnumerable<string>? includeNames = null,
bool omitQueryArguments = false)
where TReturn : class =>
GraphQlService.AddNavigationListField(this, name, resolve, graphType, includeNames, omitQueryArguments);

public FieldBuilder<TSource, TReturn> AddNavigationListField<TReturn, TProjection>(
string name,
Expression<Func<TSource, TProjection>> projection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@
//Navigation fields will always be on a typed graph. so use ComplexGraphType not IComplexGraphType
public partial interface IEfGraphQLService<TDbContext>
{
[Obsolete("Use the projection-based overload instead")]
FieldBuilder<TSource, TReturn> AddNavigationField<TSource, TReturn>(ComplexGraphType<TSource> graph,
string name,
Func<ResolveEfFieldContext<TDbContext, TSource>, TReturn?>? resolve = null,
Type? graphType = null,
IEnumerable<string>? includeNames = null)
where TReturn : class;

FieldBuilder<TSource, TReturn> AddNavigationField<TSource, TReturn, TProjection>(
ComplexGraphType<TSource> graph,
string name,
Expand All @@ -26,16 +18,6 @@ FieldBuilder<TSource, TReturn> AddNavigationField<TSource, TReturn>(
Type? graphType = null)
where TReturn : class;

[Obsolete("Use the projection-based overload instead")]
FieldBuilder<TSource, TReturn> AddNavigationListField<TSource, TReturn>(
ComplexGraphType<TSource> graph,
string name,
Func<ResolveEfFieldContext<TDbContext, TSource>, IEnumerable<TReturn>>? resolve = null,
Type? itemGraphType = null,
IEnumerable<string>? includeNames = null,
bool omitQueryArguments = false)
where TReturn : class;

FieldBuilder<TSource, TReturn> AddNavigationListField<TSource, TReturn, TProjection>(
ComplexGraphType<TSource> graph,
string name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,6 @@
//Navigation fields will always be on a typed graph. so use ComplexGraphType not IComplexGraphType
public partial interface IEfGraphQLService<TDbContext>
{
[Obsolete("Use the projection-based overload instead")]
ConnectionBuilder<TSource> AddNavigationConnectionField<TSource, TReturn>(
ComplexGraphType<TSource> graph,
string name,
Func<ResolveEfFieldContext<TDbContext, TSource>, IEnumerable<TReturn>>? resolve = null,
Type? itemGraphType = null,
IEnumerable<string>? includeNames = null,
bool omitQueryArguments = false)
where TReturn : class;

ConnectionBuilder<TSource> AddNavigationConnectionField<TSource, TReturn, TProjection>(
ComplexGraphType<TSource> graph,
string name,
Expand Down
2 changes: 1 addition & 1 deletion src/Snippets/ProjectionSnippets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public OrderGraph(IEfGraphQLService<MyDbContext> graphQlService) :
Field<StringGraphType>("customerName")
.ResolveAsync(async context =>
{
var data = base.ResolveDbContext(context);
var data = ResolveDbContext(context);
// CustomerId is available even though it wasn't in the GraphQL query
var customer = await data.Customers
.Where(c => c.Id == context.Source.CustomerId)
Expand Down