首页 > 解决方案 > 如何使用 efCore 3 和 .net core 3 在程序中修复“方法‘ApplyServices’没有实现”

问题描述

我正在 EfCore 3 和 .net core 3 上开发一个新的 Web API,但由于来自程序集“Microsoft .EntityFrameworkCore.SqlServer, Version=3.0.0.0' 没有实现。

我应该注意,我注入到我的项目中的 ApplicationContext 位于另一个项目中(也是.net core 3)。调试显示应用程序在这部分代码中崩溃 -->


    services
                    .AddDbContext<ApplicationContext>(options =>
                        options.UseSqlServer(connectionString));

在这里你可以看到所有启动类


    public Startup(IConfiguration configuration)
            {
                _configuration = configuration;
            }

            private readonly IConfiguration _configuration;

            public void ConfigureServices(IServiceCollection services)
            {
                services.AddOptions();

                var connectionString = _configuration.GetConnectionString("DefaultConnection");

                services
                    .AddDbContext<ApplicationContext>(options =>
                        options.UseSqlServer(connectionString));

                services.AddControllers()
                    .SetCompatibilityVersion(CompatibilityVersion.Latest)
                    .AddNewtonsoftJson(options =>
                    options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

                services.AddHostedService<MigratorHostedService>();
            }

            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                app.UseCors("AllowAll");

                app.UseStaticFiles();

                app.UseRouting();
            } 

这是 MigratorHostedService


    private readonly IServiceProvider _serviceProvider;
            public MigratorHostedService(IServiceProvider serviceProvider)
            {
                _serviceProvider = serviceProvider;
            }

            public async Task StartAsync(CancellationToken cancellationToken)
            {
                using (var scope = _serviceProvider.CreateScope())
                {
                    var myDbContext = scope.ServiceProvider.GetRequiredService<ApplicationContext>();

                    await myDbContext.Database.MigrateAsync();
                }
            }

            public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; 

这是程序

 private const int Port = ...;

        public static async Task Main()
        {
            var cts = new CancellationTokenSource();

            var host = Host.CreateDefaultBuilder();

            host.ConfigureWebHostDefaults(ConfigureWebHost);

            await host.Build()
                .RunAsync(cts.Token)
                .ConfigureAwait(false);
        }

        private static void ConfigureWebHost(IWebHostBuilder builder)
        {
            builder.UseUrls($"http://*:{Port}");
            builder.UseStartup<Startup>();
            builder.UseDefaultServiceProvider((context, options) =>
            {
                options.ValidateOnBuild = true;
            });
        } 

由于 .net core 3 是新的,我还没有找到解决这个问题的方法

还有我的项目包:


    <Project Sdk="Microsoft.NET.Sdk.Web">

      <PropertyGroup>
        <TargetFramework>netcoreapp3.0</TargetFramework>
        <NoWarn>$(NoWarn);NU1605</NoWarn>
      </PropertyGroup>

      <ItemGroup>
        <PackageReference Include="JetBrains.Annotations" Version="2019.1.3" />
        <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.0.0-preview-18579-0056" />
        <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0-preview.19080.1" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0">
          <PrivateAssets>all</PrivateAssets>
          <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        </PackageReference>
        <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.0.0-preview.19080.1" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.0-preview.19080.1" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.6" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0">
          <PrivateAssets>all</PrivateAssets>
          <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        </PackageReference>
        <PackageReference Include="Microsoft.NETCore.DotNetAppHost" Version="3.0.0" />
        <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Utils" Version="3.0.0" />
        <PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
      </ItemGroup>

    </Project>

应用程序上下文

public ApplicationContext(DbContextOptions<ApplicationContext> options) : base(options)
        {

        } 

标签: c#.net-core-3.0ef-core-3.0

解决方案


毕竟尝试了正确的启动实现

public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
                x => x.MigrationsAssembly("CRM.API")));

            services.AddCors(options =>
            {
                options.AddPolicy("AllowAll",
                    builder =>
                    {
                        builder
                            .AllowAnyOrigin()
                            .AllowAnyMethod()
                            .AllowAnyHeader();
                        //.AllowCredentials();
                    });
            });

            services.AddControllers().AddNewtonsoftJson(options =>
                options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
        }
        
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseStaticFiles();

            app.UseRouting();

            app.UseCors("AllowAll");

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Departments}/{action=GetDepartments}/{id?}");
            });
        }

并且正确的程序类实现在那里

public static async Task Main(string[] args)
        {
            var host = BuildWebHost(args);

            using (var scope = host.Services.CreateScope())
            {
                var services = scope.ServiceProvider;
                try
                {
                    var context = services.GetRequiredService<ApplicationContext>();

                    await context.Database.MigrateAsync();
                    await DbInitializer.InitializeAsync(context);
                }
                catch (Exception ex)
                {
                    var logger = services.GetRequiredService<ILogger<Program>>();
                    logger.LogError(ex, "An error occurred while seeding the database.");
                }
            }

            host.Run();
        }


        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();

当然,这个答案会帮助你


推荐阅读