在 Worker 中注入 Context 时出现 TypeLoadException

问题描述

我目前有一个 Razor 页面应用程序(Core 3.1)使用 IdentityDbContext 连接到一个带有上下文的 sql 数据库。在我的 Worker Service 中尝试使用相同的上下文时,我继续收到此错误

System.TypeLoadException: 'Method'Create' in type 'Microsoft.EntityFrameworkCore.sqlServer.Query.Internal.sqlServersqlTranslatingExpressionVisitorFactory' 来自程序集“Microsoft.EntityFrameworkCore.sqlServer, 版本=3.1.10.0,文化=中性,PublicKeyToken=adb9793829ddae60' 没有实现。'

这是我的背景

public class WarzoneTrackerContext : IdentityDbContext<IdentityUser>
    {
        public WarzoneTrackerContext(DbContextOptions<WarzoneTrackerContext> options) : base(options)
        {

        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //if (!optionsBuilder.IsConfigured)
            //{
            //    optionsBuilder.UsesqlServer("data source=sqlCLDevComm;initial catalog=ComQuemds;integrated security=True;");
            //}
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //modelBuilder.Entity<Player>().HasData(Seed.Players());

            foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
            {
                relationship.DeleteBehavior = DeleteBehavior.Restrict;
            }

            modelBuilder.HasDefaultSchema("dbo");
            base.OnModelCreating(modelBuilder);
        }

        public DbSet<Player> Players { get; set; }

        public DbSet<Match> Matches { get; set; }

        public DbSet<PlayerLifetimeStats> PlayerLifetimeStats { get; set; }

        public DbSet<PlayerMatchStats> PlayerMatchStats { get; set; }

    }  // End of Class

这是我的 Program.cs

public class Program
    {
        public static Microsoft.Extensions.Configuration.IConfiguration Configuration { get; } = new ConfigurationBuilder()
               .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
               .AddJsonFile("appsettings.json",optional: false,reloadOnChange: true)
               .AddJsonFile($"appsettings.{Environment.GetEnvironmentvariable("DOTNET_ENVIRONMENT") ?? "Production"}.json",optional: true)
               .Build();

        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((context,config) =>
                {

                })
                .ConfigureServices((hostContext,services) =>
                {
                    IConfiguration configuration = hostContext.Configuration;

                    var optionsBuilder = new DbContextOptionsBuilder<WarzoneTrackerContext>();

                    services.AddTransient<IMatchManager,MatchManager>();
                    services.AddTransient<IPlayerManager,PlayerManager>();
                    services.AddTransient<IRapidManager,RapidManager>();
                    //services.AddTransient<IUserClaimsPrincipalFactory<ApplicationUser>,AppClaimsPrincipalFactory>();
                    //services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = false).AddRoles<IdentityRole>()
                    //    .AddEntityFrameworkStores<WarzoneTrackerContext>();

                    //services.AddScoped<WarzoneTrackerContext>(s => new WarzoneTrackerContext(optionsBuilder.Options));

                    //services.AddScoped<WarzoneTrackerContext>(services => new WarzoneTrackerContext(optionsBuilder.Options));

                    services.AddHostedService<WarzoneWorker>();

                    services.AddDbContext<WarzoneTrackerContext>(options => options.UsesqlServer(Configuration.GetConnectionString("WarzoneConnection")));
                }).UseWindowsService();
    }

这是我的工人

public class WarzoneWorker : BackgroundService
    {
        private readonly IServiceProvider services;
        private readonly ILogger<WarzoneWorker> _logger;

        public WarzoneWorker(IServiceProvider _services,ILogger<WarzoneWorker> logger)
        {
            services = _services;
            _logger = logger;
        }

        public override async Task StartAsync(CancellationToken cancellationToken)
        {
            await base.StartAsync(cancellationToken);
        }

        public override async Task StopAsync(CancellationToken cancellationToken)
        {
            // DO YOUR STUFF HERE
            await base.StopAsync(cancellationToken);
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                using (var scope = services.CreateScope())
                {
                    var context = scope.ServiceProvider.GetrequiredService<WarzoneTrackerContext>();

                    var matchManager = scope.ServiceProvider.GetService<IMatchManager>();
                    var playerManager = scope.ServiceProvider.GetService<IPlayerManager>();
                    var rapidManager = scope.ServiceProvider.GetService<IRapidManager>();

                    _logger.Loginformation("Worker running at: {time}",DateTimeOffset.Now);
                    await Task.Delay(300000,stoppingToken);
                }
            }
        }

        public override void dispose()
        {
            // DO YOUR STUFF HERE
        }
    } 

希望有人能帮助我解决这个问题。

解决方法

请转到 Package Manager Console 并运行 dotnet restore 命令。

检查您使用的 EF 包的版本。在 .csproj 中检查您的软件包版本。如果您使用的是 preview 版本,请将所有软件包升级到最新的稳定版本。