### Example Bulk Data Loader Implementation Source: https://entitygraphql.github.io/docs/schema-creation/other-data-sources An example implementation of a bulk data loader method that fetches multiple users by their IDs. ```csharp // Example of this above public IDictionary GetAllUsers(IEnumerable data) {} ``` -------------------------------- ### Sample Incoming JSON Request Source: https://entitygraphql.github.io/docs/getting-started An example of a JSON request structure for a GraphQL mutation with variables. ```json { "query": "mutation Mutate($var: ComplexInputType){ doUpdate($var) }", "variables": { "var": { "name": "Lisa", "lastName": "Simpson" } } } ``` -------------------------------- ### PascalCase JSON Request Example Source: https://entitygraphql.github.io/docs/serialization-naming Illustrates the expected JSON request format when using PascalCase naming conventions for queries. ```json { "Query": "query { People { Id FirstName } }" } ``` -------------------------------- ### Define Data Models Source: https://entitygraphql.github.io/docs/getting-started Define your data models using C# classes. This example shows a typical setup with Entity Framework Core, but EntityGraphQL works with any LINQ-compatible data source. ```csharp public class DemoContext : DbContext { public DbSet Movies { get; set; } public DbSet People { get; set; } public DbSet Actors { get; set; } } public class Movie { public uint Id { get; set; } public string Name { get; set; } public Genre Genre { get; set; } public DateTime Released { get; set; } public List Actors { get; set; } public List Writers { get; set; } public Person Director { get; set; } public uint? DirectorId { get; set; } public double Rating { get; internal set; } } public class Actor { public uint PersonId { get; set; } public Person Person { get; set; } public uint MovieId { get; set; } public Movie Movie { get; set; } } public class Writer { public uint PersonId { get; set; } public Person Person { get; set; } public uint MovieId { get; set; } public Movie Movie { get; set; } } public enum Genre { Action, Drama, Comedy, Horror, Scifi, } public class Person { public uint Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime Dob { get; set; } public List ActorIn { get; set; } public List WriterOf { get; set; } public List DirectorOf { get; set; } public DateTime? Died { get; set; } public bool IsDeleted { get; set; } } ``` -------------------------------- ### Mutation Method Signature Source: https://entitygraphql.github.io/docs/schema-creation/mutations Example mutation method signature demonstrating parameters including context, arguments, a scalar, and a service. ```csharp public Expression> AddPerson(DemoContext db, AddPersonArgs args, string token, IDemoService demoService) {} ``` -------------------------------- ### Schema Example: No Attributes Source: https://entitygraphql.github.io/docs/schema-creation/mutations Illustrates an incorrect schema generation when arguments like `args` and `demoService` are not explicitly marked, leading EntityGraphQL to treat them as services. ```graphql type Mutation { addPerson(args: AddPersonArgs, token: String, demoService: IDemoService) } ``` -------------------------------- ### Schema Example: GraphQLArgumentsAttribute Source: https://entitygraphql.github.io/docs/schema-creation/mutations Demonstrates the correct schema generation when `GraphQLArgumentsAttribute` is used, exposing `firstName`, `lastName`, and `token` as distinct arguments. ```graphql type Mutation { addPerson( firstName: String lastName: String token: String ) } ``` -------------------------------- ### Create GraphQL API Endpoint in ASP.NET Core Source: https://entitygraphql.github.io/docs/getting-started Set up a GraphQL endpoint using EntityGraphQL.AspNet. This example configures an in-memory database and maps the GraphQL schema. ```csharp using EntityGraphQL.AspNet; var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext(opt => opt.UseInMemoryDatabase("Demo")); builder.Services.AddGraphQLSchema(); var app = builder.Build(); app.MapGraphQL(); app.Run(); ``` -------------------------------- ### GraphQL Query for Projects with Creator Details Source: https://entitygraphql.github.io/docs/schema-creation/other-data-sources This is an example GraphQL query that requests project details, including the name of the user who created the project. ```graphql { projects { name id createdBy { name } } } ``` -------------------------------- ### Schema Example: GraphQLInputTypeAttribute Source: https://entitygraphql.github.io/docs/schema-creation/mutations Shows the resulting schema where `args` is treated as a distinct input type (`AddPersonArgs`), alongside the `token` argument. ```graphql type Mutation { addPerson( args: AddPersonArgs token: String ) } ``` -------------------------------- ### GraphQL Query for Users and Their Projects Source: https://entitygraphql.github.io/docs/schema-creation/other-data-sources Example GraphQL query demonstrating how to fetch user information along with their associated projects, leveraging the connection established between the `User` type and the core context. ```graphql query { users { name projects { name summary } } } ``` -------------------------------- ### GraphQL Sort Input Type Example Source: https://entitygraphql.github.io/docs/field-extensions/sorting The UseSort extension generates a SortInput type for sorting. This example shows the generated input type for a Person class. ```graphql input PeopleSortInput { id: SortDirectionEnum firstName: SortDirectionEnum lastName: SortDirectionEnum dob: SortDirectionEnum died: SortDirectionEnum isDeleted: SortDirectionEnum } enum SortDirectionEnum { ASC DESC } ``` -------------------------------- ### GraphQL Query Example Matching Schema Casing Source: https://entitygraphql.github.io/docs/serialization-naming Demonstrates how GraphQL queries must match the schema's casing (camelCase by default) to be successful. Incorrect casing will result in errors. ```graphql { # will work people { id firstName } # will fail People { id firstName } } ``` -------------------------------- ### Execute GraphQL Query in Custom Controller Source: https://entitygraphql.github.io/docs/getting-started Example of an ASP.NET controller that receives a QueryRequest and executes a GraphQL query using the SchemaProvider. ```csharp [Route("graphql")] public class QueryController : Controller { private readonly DemoContext _dbContext; private readonly SchemaProvider _schemaProvider; public QueryController(DemoContext dbContext, SchemaProvider schemaProvider) { this._dbContext = dbContext; this._schemaProvider = schemaProvider; } [HttpPost] public async Task Post([FromBody]QueryRequest query) { var results = await _schemaProvider.ExecuteRequestWithContextAsync(query, _dbContext, HttpContext.RequestServices, null); // gql compile errors show up in results.Errors return results; } } ``` -------------------------------- ### Querying with Connection Paging Source: https://entitygraphql.github.io/docs/field-extensions/paging An example GraphQL query demonstrating how to fetch paginated data using the connection model, including specifying page size and retrieving cursor and node information. ```graphql movies(first: 4, after: "MQ==") { edges { cursor node { # this is your expected Movie context name } } pageInfo { hasPreviousPage hasNextPage startCursor endCursor } totalCount } ``` -------------------------------- ### Mutation Using Projectable Function Source: https://entitygraphql.github.io/docs/library-compatibility/expression-reuse Example of a mutation that utilizes a projectable function (Age()) within a select statement. ```csharp public class PeopleMutations { [GraphQLMutation("Add a new person to the system")] public Expression> UpdatePerson(DemoContext db, int id, string firstName, string lastName) { var person = db.People.Select(p => { p.FirstName, p.LastName, p.Age() }); ... } } ``` -------------------------------- ### GraphQL Schema Example with Default Naming Source: https://entitygraphql.github.io/docs/serialization-naming Illustrates the default camelCase naming convention used in the generated GraphQL schema for fields and arguments, derived from C# naming. ```graphql schema { query: Query } Type Query { people: [Person] person(id: ID!): Person } Type Person { id: ID! firstName: String! ... } ``` -------------------------------- ### PascalCase JSON Result Example Source: https://entitygraphql.github.io/docs/serialization-naming Shows the expected JSON result format when using PascalCase naming conventions for data returned from the GraphQL query. ```json { "People": [ { "Id": "123", "FirstName": "Bob" }, ... ] } ``` -------------------------------- ### GraphQL Subscription Operation Source: https://entitygraphql.github.io/docs/schema-creation/subscriptions Example of a GraphQL subscription operation to receive messages from a chat room. This is sent by the client after establishing a connection. ```graphql subscription ChatRoom { onMessage { id user text timestamp } } ``` -------------------------------- ### GraphQL Mutation with Inline Arguments for Simple Parameters Source: https://entitygraphql.github.io/docs/schema-creation/mutations Example of a GraphQL mutation using inline arguments with a method that accepts simple parameters and an IArgumentsTracker. It shows how only provided arguments are updated. ```graphql # Only name and email are provided - age will not be updated mutation { updatePersonSimple( id: "123e4567-e89b-12d3-a456-426614174000" name: "John Doe" email: null ) { id name age email } } ``` -------------------------------- ### Secure GraphQL Route with Authorization Policies Source: https://entitygraphql.github.io/docs/getting-started Configure authorization for your GraphQL endpoint by chaining `.RequireAuthorization()` with policy names. This example demonstrates adding a single policy. ```csharp //in ConfigureServices services.AddAuthentication() services.AddAuthorization (options => { options.AddPolicy("authorized", policy => policy.RequireAuthenticatedUser()); }); //in Configure app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints (endpoints => { // defaults to /graphql endpoint endpoints.MapGraphQL(configureEndpoint: (endpoint) => { endpoint.RequireAuthorization("authorized"); // do other things with endpoint }); }); ``` -------------------------------- ### C# Example of EntityGraphQL Service Field Resolution Source: https://entitygraphql.github.io/docs/library-compatibility/entity-framework Illustrates how EntityGraphQL splits EF Core queries into two parts: one for the main context and another for service fields, enabling EF optimizations. ```csharp var dbResultFunc = (DbContext context) => context.People.Select(p => new { p_Birthday = p.Birthday, // extracted from the Resolve expression as it is needed in the in-memory resolution manager = new { name = p.Manager.Name } }) .ToList(); // EF will fetch data var dbResult = dbResultFunc(dbContext); // executes the expression // note dbResult is an anonymous type known at runtime var resultsFunc = (AnonType dbResult, AgeService ager) => dbResult.Select(p => { age = ager.GetAge(p.p_Birthday), // passing in data we selected just for this manager = p.manager // simple selection from the previous result }) .ToList(); var results = resultsFunc(dbResult, ager); // execute for the final result ``` -------------------------------- ### Define Abstract and Concrete Types for GraphQL Interfaces Source: https://entitygraphql.github.io/docs/schema-creation/interface-types Define abstract base classes and concrete types that implement them. This setup is used to create GraphQL interfaces. ```csharp public abstract class Character { public int Id { get; set; } public string Name { get; set; } public IEnumerable Friends { get; set; } public IEnumerable AppearsIn { get; set; } } public class Human : Character { public IEnumerable Starships { get; set; } public int TotalCredits { get; set;} } public class Droid : Character { public string PrimaryFunction { get; set;} } // creating our schema schema.AddInterface(name: "Character", description: "represents any character in the Star Wars trilogy"); .AddAllFields(); schema.AddType("") .AddAllFields() .Implements(); schema.AddType("") .Implements(); ``` -------------------------------- ### GraphQL Query Example Source: https://entitygraphql.github.io/docs/schema-creation/other-data-sources A sample GraphQL query attempting to access the `agesOfActorsAtRelease` field from the `movies` type. This query will fail with the direct method field implementation. ```graphql { movies { title released agesOfActorsAtRelease } } ``` -------------------------------- ### Full PascalCase Serialization Example Source: https://entitygraphql.github.io/docs/serialization-naming Configures EntityGraphQL to use PascalCase for both request deserialization and response serialization, and sets the field namer to preserve original casing. This is useful when your API strictly uses PascalCase. ```csharp var jsonOptions = new JsonSerializerOptions { // the internal generated types use fields so include this IncludeFields = true, }; jsonOptions.Converters.Add(new JsonStringEnumConverter()); jsonOptions.Converters.Add(new RuntimeTypeJsonConverter()); services.AddSingleton(new DefaultGraphQLRequestDeserializer(jsonOptions)); services.AddSingleton(new DefaultGraphQLResponseSerializer(jsonOptions)); services.AddGraphQLSchema(options => { options.FieldNamer = name => name; }); ``` -------------------------------- ### Mark Method as Projectable Source: https://entitygraphql.github.io/docs/schema-creation/fields Marks a method with the Projectable attribute to enable EF translation via source generators. This specific example will fail with Projectables but works with lazy loading. ```csharp [GraphQLField] [Projectable] public uint DirectorAgeAtRelease => (uint)((Released - Director.Dob).Days / 365); ``` -------------------------------- ### Example GraphQL Schema with Enum Source: https://entitygraphql.github.io/docs/schema-creation/enum-types Illustrates the GraphQL schema generated from the C# enum definition, showing the 'Gender' enum and its usage within the 'Person' type. ```graphql enum Gender { Female Male NotSpecified } type Person { firstName: String lastName: String gender: Gender } ``` -------------------------------- ### GraphQL Query for Specific Metrics Source: https://entitygraphql.github.io/docs/schema-creation/other-data-sources Example GraphQL query to retrieve only the 'totalWebhooks' metric. This demonstrates how EntityGraphQL optimizes execution by only calling the necessary service method. ```graphql { metrics { totalWebhooks } } ``` -------------------------------- ### Expression Tree for Mutation Result Selection Source: https://entitygraphql.github.io/docs/schema-creation/mutations An example of the expression tree EntityGraphQL builds for selecting fields from a mutation result. This enables efficient data loading, especially with ORMs. ```csharp (DemoContext ctx) => ctx.People .Where(p => p.Id == ) .Select(p => new { id = p.Id, firstName = p.FirstName, fullName = $"{p.FirstName} {p.LastName}" }) .First() ``` -------------------------------- ### Resolving a List of Users from a Service Source: https://entitygraphql.github.io/docs/schema-creation/other-data-sources Integrate a service to resolve a list of complex objects, such as users. Ensure the complex type (e.g., `User`) is added to the schema. This example adds a 'users' query field that resolves using `IUserService`. ```csharp schema.Query().AddField("users", "Get list of users") .Resolve( // ctx is the core context we created the schema with. For this field we don't use it (ctx, srv) => srv.GetUsers() ); schema.AddType("User", "User information") .AddAllFields(); public class UserService : IUserService { public List GetUsers() { ... } } public class User { public int Id { get; set; } public string Email { get; set; } } ``` -------------------------------- ### Override Field Naming and Manually Configure Schema Source: https://entitygraphql.github.io/docs/serialization-naming This example shows how to override the default field namer and then manually add fields to the schema, ensuring consistency between .NET naming and GraphQL schema naming. ```csharp services.AddGraphQLSchema(options => { options.FieldNamer = name => name; // use the dotnet name as is options.ConfigureSchema = schema => { schema.Query().AddField("SomeField", ...) }; }); ``` -------------------------------- ### Movie Class with Method Field Source: https://entitygraphql.github.io/docs/schema-creation/other-data-sources Example of a Movie class with a method field `AgesOfActorsAtRelease` that uses an injected service `IAgeCalculator`. This approach is not directly supported by EntityGraphQL for service fields. ```csharp public class Movie { public int Id { get; set; } // ... [GraphQLField] public uint[] AgesOfActorsAtRelease(IAgeCalculator calc) { List ages = calc.CalculateAges(Released, Actors); return ages } } public class AgeCalculator : IAgeCalculator { public List CalculateAges(DateTime released, IEnumerable) { var ages = new List(); foreach (var actor in actors) { ages.Add((uint)((released - actor.Person.Dob).Days / 365)); } return ages.ToArray(); } } ``` -------------------------------- ### Registering and Injecting a Service in Startup.cs Source: https://entitygraphql.github.io/docs/schema-creation/mutations Register your service in `Startup.cs` and then include it as a parameter in your mutation method to enable dependency injection. ```csharp // in Startup.cs services.AddSingleton(); ``` -------------------------------- ### Default Scalar Type Setup Source: https://entitygraphql.github.io/docs/schema-creation/scalar-types EntityGraphQL automatically sets up several common .NET types as scalar types upon schema creation. This includes integers, floating-point numbers, booleans, strings, GUIDs, and date/time related types. ```csharp AddScalarType("Int", "Int scalar"); AddScalarType("Float", "Float scalar"); AddScalarType("Boolean", "Boolean scalar"); AddScalarType("String", "String scalar"); AddScalarType("ID", "ID scalar"); AddScalarType("Char", "Char scalar"); AddScalarType("Date", "Date with time scalar"); AddScalarType("DateTimeOffset", "DateTimeOffset scalar"); AddScalarType("DateOnly", "Date value only scalar"); AddScalarType("TimeOnly", "Time value only scalar"); ``` -------------------------------- ### Configure Output Caching in Program.cs Source: https://entitygraphql.github.io/docs/library-compatibility/caching Demonstrates how to register output caching services, set up the middleware, and configure caching for GraphQL endpoints in the main application file. ```csharp var builder = WebApplication.CreateBuilder(args); [...] builder.Services.AddOutputCache(); [...] var app = builder.Build(); [...] app.UseOutputCache(); [...] app.MapGraphQL( configureEndpoint: endpointConventionBuilder => endpointConventionBuilder.CacheOutput(outputCachePolicyBuilder => { // Support HTTP POST requests, not supported by default outputCachePolicyBuilder.AddPolicy(); outputCachePolicyBuilder.VaryByValue(httpContext => { httpContext.Request.EnableBuffering(); var initialBodyStreamPosition = httpContext.Request.Body.Position; httpContext.Request.Body.Position = 0; using var bodyReader = new StreamReader(httpContext.Request.Body, leaveOpen: true); var bodyContent = bodyReader.ReadToEndAsync() .Result .Replace(" ", ""); httpContext.Request.Body.Position = initialBodyStreamPosition; return new KeyValuePair("requestBody", bodyContent); }); outputCachePolicyBuilder.Expire(TimeSpan.FromSeconds(MedicalDataApiConstants.OutputCache.DefaultExpireSeconds)); } )); ``` -------------------------------- ### Connection Paging with Arguments Source: https://entitygraphql.github.io/docs/field-extensions/paging Demonstrates how to use `UseConnectionPaging()` with custom arguments like 'year' and 'orderByRelease', merging them with paging arguments for dynamic data retrieval. ```csharp schemaProvider.ReplaceField("movies", new { year = (int?)null, orderByRelease = (bool?)null }, (db, args) => db.Movies .WhereWhen(m => m.Released.Year == args.year, args.year.HasValue) .OrderBy(e => args.orderByRelease ? e.Released : e.Id) "Get a page of movies" ) .UseConnectionPaging(); ``` -------------------------------- ### Filtering by Date and Boolean Source: https://entitygraphql.github.io/docs/field-extensions/filtering Example combining date comparison and a boolean condition in the 'filter' argument. ```graphql { people(filter: "dob > \"2010-08-11T00:00:00\" && isDeleted == false") { firstName } } ``` -------------------------------- ### Filtering People by ID Source: https://entitygraphql.github.io/docs/field-extensions/filtering Example of filtering a list of people by their IDs using the 'filter' argument. ```graphql { people(filter: "id == 12 || id == 10") { firstName } } ``` -------------------------------- ### Conceptual Code for Bulk Loading Process Source: https://entitygraphql.github.io/docs/schema-creation/other-data-sources This code illustrates the conceptual steps involved in bulk loading data, from initial selection to calling the bulk service and mapping results. ```csharp // before we bulk load service data var data = ctx.Projects.Select(p => new { name = p.Name, id = p.Id p.CreatedById }); // We now select the keys using the keySelector from ResolveBulk var projectUserKeys = data.Projects.SelectMany(p => p.CreatedById); // call service bulk loader var projectUsers = userService.GetAllUsers(projectUserKeys); // Now we can select out the query fields var result = data.Select(p => new { p.name, p.id user = new { name = projectUsers[p.CreatedById].Name, // ... any other fields } }); ``` -------------------------------- ### Configure Default and Max Page Size Source: https://entitygraphql.github.io/docs/field-extensions/paging Sets optional default and maximum page sizes for the offset paging model. If 'take' is null, defaultPageSize is used. If 'take' exceeds maxPageSize, an error occurs. ```csharp myField .UseOffsetPaging( defaultPageSize: 10, maxPageSize: 50 ) ``` -------------------------------- ### GraphQL Query Demonstrating Resolve and ResolveBulk Usage Source: https://entitygraphql.github.io/docs/schema-creation/other-data-sources This query shows how to fetch projects using ResolveBulk for the 'createdBy' field and a single project using the standard Resolve for its 'createdBy' field. ```graphql { # ResolveBulk projects { # project fields name id # service field - resolved with ResolveBulk expression for all Projects loaded createdBy { name } } # Resolve project(id: 78) { # project fields name id # service field - resolved with Resolve service expression for the single project loaded createdBy { name } } } ``` -------------------------------- ### GraphQL Query for Movie Director Age Source: https://entitygraphql.github.io/docs/schema-creation/fields Example GraphQL query to retrieve movie names and the director's age at release. ```graphql { movies { name directorAgeAtRelease } } ``` -------------------------------- ### Implement Connection Paging for a Field Source: https://entitygraphql.github.io/docs/field-extensions/paging Applies the `UseConnectionPaging()` extension to a field to enable the Connection Model. It's recommended to order the field's results for consistent paging. ```csharp schemaProvider.ReplaceField("movies", db => db.Movies.OrderBy(e => e.Id) // best to give the field an order so pages are the same "Get a page of movies" ) .UseConnectionPaging(); ``` -------------------------------- ### Implement Custom Deprecation Directive Source: https://entitygraphql.github.io/docs/directives/schema-directives Example of extending IField with a Deprecate method and handling ObsoleteAttribute to automatically add the @deprecated directive. ```csharp public static class DeprecatedDirectiveExtensions { public static void Deprecate(this IField field, string? reason) { field.AddDirective(new DeprecatedDirective(reason)); } } public class ObsoleteAttributeHandler : AbstractExtensionAttributeHandler { public void ApplyExtension(IField field, ObsoleteAttribute attribute) { field.Deprecate(attribute.Message); } } ``` -------------------------------- ### Configuring Bulk and Simple Resolvers Source: https://entitygraphql.github.io/docs/schema-creation/other-data-sources This snippet demonstrates how to configure both a standard resolver and a bulk resolver for the 'createdBy' field on the Project type. Use ResolveBulk for efficient loading of multiple related entities. ```csharp schema.UpdateType(type => { type.AddField("createdBy", "Get the user details of user that created this project") // normal service to fetch the User object for creator of the Project type .Resolve((proj, users) => users.GetUserById(proj.CreatedById)) // Bulk service used to fetch many User objects .ResolveBulk(proj => proj.CreatedById, (ids, srv) => srv.GetAllUsers(ids)); }); ``` -------------------------------- ### Generated GraphQL Schema for addNewPerson Mutation Source: https://entitygraphql.github.io/docs/schema-creation/mutations Example of how a mutation with arguments is represented in the GraphQL schema. Arguments that EntityGraphQL cannot resolve are added to the schema. ```graphql type Mutation { addNewPerson(firstName: String, lastName: String): Person! } ``` -------------------------------- ### Query Movie Data Source: https://entitygraphql.github.io/ Example GraphQL query to retrieve movie details including its name, genre, and associated actors' IDs and names. ```graphql query MyQuery { movie(id: 19) { name genre actors { id name } } } ``` -------------------------------- ### Configure Application Services and Endpoints Source: https://entitygraphql.github.io/docs/schema-creation/subscriptions Register the ChatService, configure the GraphQL schema with mutations and subscriptions, and enable WebSockets and GraphQL WebSockets endpoints. ```csharp // ... builder.Services.AddSingleton(); builder.Services.AddGraphQLSchema(options => { options.ConfigureSchema = (schema) => { schema.Mutation().AddFrom(); schema.Subscription().AddFrom(); } }); var app = builder.Build(); // ... app.UseWebSockets(); app.UseRouting(); app.UseGraphQLWebSockets(); app.UseEndpoints(endpoints => { endpoints.MapGraphQL(); }); app.Run(); ``` -------------------------------- ### Add Sort to List Fields Source: https://entitygraphql.github.io/docs/schema-creation Example callback for `OnFieldCreated` to automatically apply sorting functionality to all list fields in the schema, provided they are not on an interface type. ```csharp // Add Sort to all list fields OnFieldCreated = (field) => { if (field.ReturnType.IsList && field.ReturnType.SchemaType.GqlType == GqlTypes.QueryObject && !field.FromType.IsInterface) { field.UseSort(); } } ``` -------------------------------- ### Implementing IArgumentsTracker for Input Classes Source: https://entitygraphql.github.io/docs/getting-started Shows how to use the ArgumentsTracker base class for input objects to track which properties were set by the user. ```csharp public class MyInput : ArgumentsTracker { public string? Name { get; set; } public int? Age { get; set; } } // For a field schema.Query().AddField("test", new MyInput(), (db, args) => db.People.WhereWhen(p => args.Name == p.Name, args.IsSet(nameof(MyInput.Name))), "test field"); // In your mutation or subscriptions public string MyMutation(MyInput input) { if (input.IsSet(nameof(MyInput.Name))) { // Name was provided in the query } if (!input.IsSet(nameof(MyInput.Age))) { // Age was not provided } ... } ``` -------------------------------- ### Add GraphQL Type to Schema Source: https://entitygraphql.github.io/docs/schema-creation Register a .NET type as a GraphQL object type within your schema. This example adds a 'Person' type with a description. ```csharp schema.AddType("Person", "Hold data about a person object"); ``` -------------------------------- ### Querying with Inline Fragments on Interfaces Source: https://entitygraphql.github.io/docs/schema-creation/interface-types Demonstrates how to query fields from an interface and specific fields from implementing types using inline fragments. ```graphql query { characters { name ... on Human { totalCredits } ... on Droid { primaryFunction } } } ``` -------------------------------- ### Add Type and All Fields Source: https://entitygraphql.github.io/docs/schema-creation Adds a .NET type to the schema with a specified name and description, then automatically includes all its fields. ```csharp schema.AddType("Person", "All about the project") .AddAllFields(); ``` -------------------------------- ### Projectable Method Failing with EF Source: https://entitygraphql.github.io/docs/schema-creation/fields Example of a method that cannot be translated by EntityFrameworkCore.Projectables because it involves complex logic (looping and list manipulation). It works with lazy loading. ```csharp [GraphQLField] [Projectable] // will fail as it can't generate an expression - does work with lazy loading public uint[] AgesOfActorsAtRelease() { var ages = new List(); foreach (var actor in Actors) { ages.Add((uint)((Released - actor.Person.Dob).Days / 365)); } return ages.ToArray(); } ``` -------------------------------- ### Mutation Request with Nested Fields (ID only) Source: https://entitygraphql.github.io/docs/schema-creation/mutations Example GraphQL mutation request asking for only the 'id' field of the returned object. Demonstrates selective field fetching. ```graphql mutation { addNewPerson(firstName: "Bill", lastName: "Murray") { id } } ``` -------------------------------- ### Using IArgumentsTracker for Simple Argument Lists Source: https://entitygraphql.github.io/docs/getting-started Demonstrates how to use IArgumentsTracker as a parameter in mutation or query methods to check if specific arguments were provided. ```csharp public string MyMutation(Guid? id, string? name, IArgumentsTracker argsTracker) { if (argsTracker.IsSet(nameof(id))) { // id was provided } if (!argsTracker.IsSet(nameof(name))) { // name was not provided } ... } ``` -------------------------------- ### Add Root Query Field Source: https://entitygraphql.github.io/docs/schema-creation Define a top-level query field for your GraphQL schema. This example adds a 'people' field that resolves to a list of people from the context. ```csharp schema.Query() // returns the root GraphQL query type .AddField( "people", ctx => ctx.People, // ctx is the core context used when creating the schema above "List of people" ); ``` -------------------------------- ### Build Schema from Context Source: https://entitygraphql.github.io/docs/schema-creation Automatically add all types and fields from the base context to create a schema. ```csharp var schema = SchemaBuilder.FromObject(); ``` -------------------------------- ### Enable Query Information in Execution Options Source: https://entitygraphql.github.io/docs/integration Set `IncludeQueryInfo` to true in `ExecutionOptions` to capture detailed query execution data. This is useful for query analysis and debugging. ```csharp var options = new ExecutionOptions { IncludeQueryInfo = true }; var result = schema.ExecuteRequestWithContext(request, context, serviceProvider, user, options); ``` -------------------------------- ### Set Default and Max Page Size for Connection Paging Source: https://entitygraphql.github.io/docs/field-extensions/paging Configures optional default and maximum page sizes for the connection paging model to control query results and prevent excessive data retrieval. ```csharp myField .UseConnectionPaging( defaultPageSize: 10, maxPageSize: 50 ) ``` -------------------------------- ### Configure System.Text.Json for EntityGraphQL Source: https://entitygraphql.github.io/docs/getting-started Configure System.Text.Json options for optimal compatibility with EntityGraphQL, including enum string conversion and field inclusion. ```csharp services.AddControllers() .AddJsonOptions(opts => { // Use enum field names instead of numbers opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); // EntityGraphQL internally builds types with fields opts.JsonSerializerOptions.IncludeFields = true; // The fields internally built already are named with fieldNamer (defaults to camelCase). This is // for the properties on QueryResult (Data, Errors) to match what most tools etc expect (camelCase) opts.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; }); ``` -------------------------------- ### Connecting Back to Core Context from a User Type Source: https://entitygraphql.github.io/docs/schema-creation/other-data-sources Add fields to a non-core context type (like `User`) that resolve data from the core context (e.g., `DemoContext`). Use `Resolve()` again for these connections to build a richer object graph. ```csharp schema.UpdateType(userType => { userType.AddField("tasks", "List of projects assigned to the user") .Resolve( (user, db) => db.Projects.Where(project => project.AssignedToId == user.Id) ); }); ``` -------------------------------- ### Add Field to GraphQL Type Source: https://entitygraphql.github.io/docs/schema-creation Define a field for a GraphQL type by specifying its name, a .NET expression for resolution, and a description. This example adds the 'firstName' field to the 'Person' type. ```csharp schema.UpdateType(personType => { personType.AddField( "firstName", // name in GraphQL schema person => person.FirstName, // expression to resolve the field on the .NET type "A person's first name" // description of the field ); }); ``` -------------------------------- ### EntityGraphQL's Initial Execution Plan Source: https://entitygraphql.github.io/docs/schema-creation/other-data-sources Illustrates the intermediate selection EntityGraphQL performs before attempting to resolve service fields. This selection removes the original `Movie` type, making the method field inaccessible. ```csharp (DemoContext ctx) => ctx.Movies.Select(m => new { title = m.Title, released = m.Released }).ToList(); ``` -------------------------------- ### GraphQL Mutation with Variables and Inline Arguments Source: https://entitygraphql.github.io/docs/schema-creation/mutations Demonstrates how to use variables or inline arguments with a mutation that accepts an input type implementing IArgumentsTracker. This shows how the input is passed to the server. ```graphql # Using variables mutation UpdatePerson($input: UpdatePersonInput) { updatePerson(input: $input) { id name age } } # Variables: { "input": { "name": "John", "email": null } } # Using inline arguments mutation { updatePerson(input: { name: "John", email: null }) { id name age } } ``` -------------------------------- ### Create Blank Schema (Standalone) Source: https://entitygraphql.github.io/docs/schema-creation Instantiate a blank schema provider with a base query type, allowing for manual schema configuration outside of ASP.NET Core. ```csharp var schema = new SchemaProvider(); ``` -------------------------------- ### Mutation Request with Multiple Nested Fields Source: https://entitygraphql.github.io/docs/schema-creation/mutations Example GraphQL mutation request asking for multiple fields ('id', 'firstName', 'fullName') of the returned object. Shows how to fetch related data. ```graphql mutation { addNewPerson(firstName: "Bill", lastName: "Murray") { id firstName fullName } } ``` -------------------------------- ### GraphQL Query with Variables and Inline Arguments Source: https://entitygraphql.github.io/docs/schema-creation/fields Demonstrates how to query the 'people' field using both GraphQL variables and inline arguments, showing how null values are handled. ```graphql # Using variables query GetPeople($filter: PersonFilter) { people(name: $filter.name, city: $filter.city) { id name age city } } # Variables: { "filter": { "name": "John", "city": null } } # Using inline arguments query { people(name: "John", city: null) { id name age city } } ``` -------------------------------- ### GraphQL Mutation Request to Add a Person Source: https://entitygraphql.github.io/docs/schema-creation/mutations Example of a GraphQL mutation request to add a new person using the 'addNewPerson' mutation. It specifies the arguments and selects fields to be returned in the response. ```graphql mutation { addNewPerson(firstName: "Bill", lastName: "Murray") { id fullName } } ``` -------------------------------- ### Registering and Using GraphQLValidator Service Source: https://entitygraphql.github.io/docs/validation Register the GraphQLValidator service in your startup configuration. Implement custom validation logic within your mutations using the IGraphQLValidator service to collect multiple errors. ```csharp // In your Startup.cs services.AddGraphQLValidator(); // with EntityGraphQL.AspNet // Or with your own implementation services.AddScoped(); // your mutation public class MovieMutations { [GraphQLMutation] public Expression>? AddActor(MyDbContext db, ActorArgs args, IGraphQLValidator validator) { if (string.IsNullOrEmpty(args.Name)) validator.AddError("Name argument is required"); if (args.age <= 0) validator.AddError("Age argument must be positive"); if (validator.HasErrors) return null; // do your magic here. e.g. with EF or other business logic var movie = db.Movies.First(m => m.Id == args.Id); var actor = new Person { Name = args.Name, ... }; movie.Actors.Add(actor); db.SaveChanges(); return ctx => ctx.Movies.First(m => m.Id == movie.Id); } } ``` -------------------------------- ### Globally Register EntityFrameworkCore.Projectables Source: https://entitygraphql.github.io/docs/library-compatibility/expression-reuse Register the library globally when registering the DbContext. ```csharp services.AddDbContext(opt => opt.UseSqlite("Filename=demo.db") .UseProjectables() ); ``` -------------------------------- ### Add Computed Field to GraphQL Type Source: https://entitygraphql.github.io/docs/schema-creation Add a field to a GraphQL type whose value is computed using a .NET expression. This example creates a 'fullName' field by concatenating first and last names. ```csharp schema.UpdateType(personType => { personType.AddField( "fullName", person => $"{person.FirstName} {person.LastName}", "A person's full name" ); }); ``` -------------------------------- ### Build GraphQL Schema from Object Source: https://entitygraphql.github.io/docs/getting-started Use SchemaBuilder.FromObject() to create a GraphQL schema from a .NET object model. Register the schema provider with your services. ```csharp var schema = SchemaBuilder.FromObject(); services.AddSingleton>(); ``` -------------------------------- ### Custom Paging with Skip and Take Arguments Source: https://entitygraphql.github.io/docs/field-extensions/paging Implements custom paging by defining 'skip' and 'take' arguments for a collection field. This allows direct control over pagination logic. ```csharp schemaProvider.ReplaceField( "movies", new { // add our field arguments take = 10, // defaults skip = 0 }, (db, args) => db.Movies .Skip(args.skip) // do paging .Take(args.take), "Get a page of movies" ); ``` -------------------------------- ### GraphQL Mutation with Scalar Arguments Source: https://entitygraphql.github.io/docs/schema-creation/input-types Demonstrates a GraphQL mutation call using individual scalar arguments for first and last name. ```graphql POST localhost:5000/graphql { "query": "mutation AddPerson($firstName: String!, $lastName: String!) { addNewPerson(firstName: $firstName, lastName: $lastName) { id } }", "variables": { "firstName": "Bill", "lastName": "Murray" } } ``` -------------------------------- ### GraphQL Query with @include Directive Source: https://entitygraphql.github.io/docs/directives/operation-directives This example demonstrates how to use the @include directive to conditionally include a field based on a variable. Set the 'withFriends' variable to true to include the 'friends' field, or false to exclude it. ```graphql query Hero($episode: Episode, $withFriends: Boolean!) { hero(episode: $episode) { name friends @include(if: $withFriends) { name } } } ``` -------------------------------- ### Configuring DateTimeOffset in Default Schema Source: https://entitygraphql.github.io/docs/upgrade-4-0 Example of how to remove the default `DateTimeOffset` scalar type from the schema and add it back with custom configuration in EntityGraphQL v4.x. This is useful if you want to map it to a different type, like 'Date'. ```csharp services.AddGraphQLSchema(options => { options.PreBuildSchemaFromContext = (schema) => { schema.RemoveType(); // add it how you want }; }); ``` -------------------------------- ### Implement a Chat Service with Broadcaster Source: https://entitygraphql.github.io/docs/schema-creation/subscriptions A simple ChatService that uses the Broadcaster class to broadcast new messages. The Subscribe() method returns an IObservable for subscription registration. ```csharp public class ChatService { private readonly Broadcaster broadcaster = new(); public Message PostMessage(ChatContext db, string message, string user) { var msg = new Message { Id = Guid.NewGuid(), Text = message, Timestamp = DateTime.Now, UserId = user, }; db.Messages.Add(msg); db.SaveChanges(); broadcaster.OnNext(msg); return msg; } public IObservable Subscribe() { return broadcaster; } } ``` -------------------------------- ### Integrating Attribute Handlers into Schema Builder Source: https://entitygraphql.github.io/docs/directives/schema-directives Demonstrates how to add custom attribute handlers during schema construction, either when building the schema manually or using ASP.NET Core extensions. ```csharp // If building yourself var schema = SchemaBuilder.FromObject(new SchemaBuilderSchemaOptions { PreBuildSchemaFromContext = (context) => { context.AddAttributeHandler(new AuthorizeAttributeHandler()); } }); // with the ASP.NET extensions builder.Services.AddGraphQLSchema(options => { PreBuildSchemaFromContext = (context) => { context.AddAttributeHandler(new AuthorizeAttributeHandler()); } }); ``` -------------------------------- ### Resolving Field Data from a Service Source: https://entitygraphql.github.io/docs/schema-creation/other-data-sources Use `Resolve()` to fetch data for a field from an external service. The service is resolved via `IServiceProvider` during execution. This example shows adding an 'age' field to the 'Person' type using an `IAgeService`. ```csharp schema.UpdateType(personType => { personType.AddField("age", "Person's age") .Resolve((person, srv) => srv.GetAge(person.Dob)); }); // Startup.cs services.AddSingleton(); // AgeService.cs public class AgeService { public int GetAge(DateTime dob) { return (now - dob).TotalYears; } } ``` -------------------------------- ### GraphQL Mutation with Input Type Argument Source: https://entitygraphql.github.io/docs/schema-creation/input-types Demonstrates a GraphQL mutation call using a single input type argument for person data, containing first and last name. ```graphql POST localhost:5000/graphql { "query": "mutation AddPerson($person: PersonInput!) { addNewPerson(personInput: $person) { id } }", "variables": { "personInput": { "firstName": "Bill", "lastName": "Murray" } } } ``` -------------------------------- ### Generated GraphQL Mutation Schema Source: https://entitygraphql.github.io/docs/schema-creation/mutations Illustrates the resulting GraphQL schema for the `addNewPerson` mutation, showing how arguments are exposed. ```graphql type Mutation { addNewPerson( firstName: String lastName: String middleName: String dob: String parent1Id: Int parent2Id: Int favFood: [String] ): Person! } ``` -------------------------------- ### Enable Connection Paging with Attributes Source: https://entitygraphql.github.io/docs/field-extensions/paging Uses the `UseConnectionPagingAttribute` on collection properties within a `DbContext` class when using `SchemaBuilder.FromObject` to automatically apply connection paging. ```csharp public class DemoContext : DbContext { [UseConnectionPaging] public DbSet Movies { get; set; } [UseConnectionPaging] public DbSet People { get; set; } [UseConnectionPaging] public DbSet Actors { get; set; } } ``` -------------------------------- ### Add GraphQL Schema with Auto-Build Source: https://entitygraphql.github.io/docs/schema-creation Use this extension method in ASP.NET Core to automatically build the GraphQL schema from a base query type. Configure schema customization within the options. ```csharp services.AddGraphQLSchema(options => { options.ConfigureSchema = (schema) => { // configure schema here }; }); ``` -------------------------------- ### Define and Register Union Types Source: https://entitygraphql.github.io/docs/schema-creation/union-types Demonstrates how to define marker interfaces, concrete types, and then register them as a union type with EntityGraphQL. ```csharp public interface ICharacter { } public class Human : ICharacter { ... } public class Droid : ICharacter { ... } // creating our schema var union = schema.AddUnion(name: "Character", description: "represents any character in the Star Wars trilogy"); schema.Type().AddPossibleType(); schema.Type().AddPossibleType(); ``` -------------------------------- ### Configure Projectables for EF Source: https://entitygraphql.github.io/docs/schema-creation/fields Configures the DbContext to use the Projectables library for EF compatibility with source-generated expressions. ```csharp // configure projectables services.AddDbContext(opt => opt.UseProjectables() ); ``` -------------------------------- ### Configure GraphQL Endpoint with Spec Compliance Source: https://entitygraphql.github.io/docs/getting-started Enable strict GraphQL over HTTP spec compliance for the GraphQL endpoint. This is recommended for new projects and will be the default in future versions. ```csharp app.MapGraphQL(followSpec: true); ``` -------------------------------- ### Class-Level Service Injection for Multiple Mutations Source: https://entitygraphql.github.io/docs/schema-creation/mutations Dependencies can be injected at the class level, which is useful when multiple mutations or helper methods within the class need access to the same service. ```csharp class PeopleMutations(IDemoService demoService) { private readonly IDemoService demoService; public PeopleMutations(IDemoService demoService) { this.demoService = demoService; } public Expression> AddNewPerson(DemoContext db, string firstName, string lastName) { // Use ServiceHelper } public Expression> SetPersonJob(DemoContext db, string job) { // Use ServiceHelper } void ServiceHelper(Person person) { // Use demoService } } ```