如何使用efCore 3和.net core 3修复程序中的“方法'ApplyServices'没有实现”

时间:2019-10-15 10:42:31

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

我正在EfCore 3和.net core 3上开发新的Web API,但由于出现错误“ Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal.SqlServerOptionsExtension”类型中的“方法'ApplyServices'而无法启动程序集“ Microsoft.EntityFrameworkCore.SqlServer,版本= 3.0.0.0”没有实现。

我应该注意,我注入到我的项目中的ApplicationContext位于另一个项目(也是.net核心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>

ApplicationContext

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

        } 

2 个答案:

答案 0 :(得分:0)

接口定义函数的签名-名称,参数,返回值。但是他们不能为他们定义任何代码。他们期望实现它们的类为他们提供代码。您必须给出一个实现。

现在,对于每种可想象的接口功能,这都是绝对有效的实现:

{
  throw new NotImplementedException();
}

这是

{
  throw new NotSupportedException();
}

它甚至满足了“必须返回值”规则。

它也是默认实现。在某些情况下,它可能是唯一的实现。并非每个接口的每个功能都可能对实现它的每个类都有一个明智的实现。在某些情况下,该功能未实现is even expected

如果您控制该类,则必须为该功能提供实际的实现。

如果您不控制该类,那么您在很大程度上不走运。

我看不到对ApplyServices的任何呼叫。因此,这意味着您将实例传递给期望该函数存在的某些代码(并具有明智的行为)。并非如此。

无论您希望做什么,都希望该类具有用于ApplyServices的代码,则不能将其应用于该类。应该有一种方法可以将一些代码交给函数。就像Array.Sort()的重写一样,它接受一个自定义的Comparer,而不是使用默认的Comparer。但是,如果不是这样,那简直就是不行。

答案 1 :(得分: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?}");
            });
        }

正确的Program类实现在那里

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();

好的,这个答案会帮助您