zoukankan      html  css  js  c++  java
  • Entity Framework Core with GraphQL and SQL Server using HotChocolate

    This article will cover two graphql options available for dotnet core:

    Create the project

    Prerequisites

    • VSCODE (Omnisharp + C# extensions installed)
    • SQL Server
    • .NET Core 3.1 SDK

    First, we load up our trusty terminal (CMD, Bash, ZSH, PowerShell etc.) create a project folder and navigate to it and create the project:

    > md netcore-graphql-test
    > cd netcore-graphql-test
    > dotnet new web
    

    This wil create a new empty web application. Once that's done, we install the dependencies:

    > dotnet add package Microsoft.EntityFrameworkCore
    > dotnet add package Microsoft.EntityFrameworkCore.SqlServer
    > dotnet add package HotChocolate.AspNetCore
    > dotnet add package HotChocolate.AspNetCore.Playground
    > code .
    

    This will install the above packages, and open up vscode. When you open up vscode, you may see some popups, just click install for C# extensions, wait for Omnisharp to install if it already isn't installed, and let it install any missing required assets.

    So far, our csproj file should look like this:

    <Project Sdk="Microsoft.NET.Sdk.Web">
    
      <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <RootNamespace>netcore_graphql_test</RootNamespace>
      </PropertyGroup>
    
      <ItemGroup>
        <PackageReference Include="HotChocolate.AspNetCore" Version="10.4.3" />
        <PackageReference Include="HotChocolate.AspNetCore.Playground" Version="10.4.3" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.4" />
      </ItemGroup>
    
    </Project>
    

    Startup.cs

    using HotChocolate;
    using HotChocolate.AspNetCore;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    
    namespace netcore_graphql_test
    {
        public class Startup
        {
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddGraphQL(SchemaBuilder.New()
                    // AddQueryType<T>() here 
                    .Create());
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                app.UseRouting();
    
                app.UseWebSockets()
                    .UseGraphQL()
                    .UsePlayground();
            }
        }
    }
    

    This boilerplate, will allow us to eventually use a GraphiQL style playground to test our queries.

    The Database

    In our test database for this example, lets say we have a table

    CREATE TABLE [Locations] (
      [ID] [int] IDENTITY(1,1) NOT NULL,
      [Name] [nvarchar](50) NOT NULL,
      [Code] [nvarchar](5) NOT NULL,
      [Active] [bit] NOT NULL
    )
    

    Lets insert some test data:

    INSERT INTO [Locations]
      ([Name], [Code], [Active])
    VALUES
      ('Sydney', 'SYD', 1)
    GO
    INSERT INTO [Locations]
      ([Name], [Code], [Active])
    VALUES
      ('Los Angeles', 'LAX', 1)
    GO
    

    Entity

    This is pretty much the same as your standard .NET EntityFramework entity you'd use. It's basically a class with the matching column names and types as the CREATE TABLE query above.

    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace netcore_graphql_test
    {
        [Table("Locations")]
        public class Location
        {
            [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
            public int ID { get; set; }
    
            [Required, MaxLength(50)]
            public string Name { get; set; }
    
            [Required, MaxLength(5)]
            public string Code { get; set; }
    
            [Required]
            public bool Active { get; set; }
        }
    }
    

    The DB Context

    Again, it's pretty much identical to any standard DB Context in .NET Entity Framework Core.

    using Microsoft.EntityFrameworkCore;
    
    namespace netcore_graphql_test
    {
        public class MyDbContext : DbContext
        {
            public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
            {
            }
    
            public DbSet<Location> Locations { get; set; }
        }
    }
    

    The Schema

    Hear comes the meaty part. This is what we will have access to in our graphql playground. As a basic query, we'll return a list of Locations from our Location table, and another query that accepts an argument for a specific location code. The schema is pretty straightforward, you'll have one class that has queries, and another class that extends ObjectType and configures the fields for the query. The latter will be added to our Startup.cs file as a QueryType in the Schema definition.

    First, we'll create the query class. This contains all the queries for this example.

    using HotChocolate;
    using Microsoft.EntityFrameworkCore;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace netcore_graphql_test
    {
        public class LocationQueries
        {
            /// <summary>
            /// Return a list of all locations
            /// Notice the [Service]. It's an auto look-up from HotChocolate
            /// </summary>
            /// <param name="dbContext"></param>
            /// <returns></returns>
            public async Task<List<Location>> GetLocations([Service] MyDbContext dbContext) =>
                await dbContext.Locations
                .AsNoTracking()
                .OrderBy(l => l.Name)
                .ToListAsync();
    
            
            public async Task<List<Location>> GetLocation([Service] MyDbContext dbContext, string code) =>
                await dbContext.Locations
                .AsNoTracking()
                .Where(l => l.Code == code)
                .OrderBy(l => l.Name)
                .ToListAsync();
        }
    }
    

    Next, we create the query type.

    using HotChocolate.Types;
    
    namespace netcore_graphql_test
    {
        public class LocationQueryType : ObjectType<LocationQueries>
        {
            protected override void Configure(IObjectTypeDescriptor<LocationQueries> descriptor)
            {
                base.Configure(descriptor);
    
                descriptor.Field(x => x.GetLocations(default));
    
                descriptor.Field(x => x.GetLocation(default, default))
                    .Argument("code", a => a.Type<StringType>());
            }
        }
    }
    

    This lets our schema know that we have 2 queries available. GetLocations will get all locations. GetLocation will get a location by code.

    Back to Startup.cs file

    Now that we have everything set up, we can update our Startup.cs file with the data context, and schema builder.

    To do this, the update the ConfigureServices function with the following:

    public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
            public void ConfigureServices(IServiceCollection services)
            {
                // Add DbContext
                services.AddDbContext<MyDbContext>(options =>
                {                
                    options.UseSqlServer(Configuration.GetConnectionString("Default"));
                });
    
                // Add GraphQL Services
                services
                    .AddDataLoaderRegistry()
                    .AddGraphQL(SchemaBuilder.New()
                    // LocationQueryType as a QueryType
                    .AddQueryType<LocationQueryType>().Create());
            }
    

    Build and run

    To build and run, type the following in your terminal:

    > dotnet run
    

    Open your browser to http://localhost:5000/playground. This will display a graphiql playground. In this you should be able to successfully run the queries:

    # return all locations
    
    {
      locations {
        name
        code
      }
    }
    
    # return "Los angeles"
    
    {
      location(code: "lax") {
        name
      }
    }
    

    This covers the basic fundamentals of EFCore and GraphQL. Hope it helps someone.

  • 相关阅读:
    python Database Poll for SQL SERVER
    SQLAlchemy表操作和增删改查
    flask动态url规则
    flask配置管理
    一个Flask运行分析
    Function Set in OPEN CASCADE
    Happy New Year 2016
    Apply Newton Method to Find Extrema in OPEN CASCADE
    OPEN CASCADE Multiple Variable Function
    OPEN CASCADE Gauss Least Square
  • 原文地址:https://www.cnblogs.com/matt1985/p/13023099.html
Copyright © 2011-2022 走看看