在 Worker 中注入 Context 时出现 TypeLoadException
TypeLoadException when injecting Context in Worker
我目前有一个 Razor 页面应用程序 (Core 3.1) 连接到 SQL 数据库,其上下文使用 IdentityDbContext。尝试在我的 Worker 服务中使用相同的上下文时,我继续收到此错误:
System.TypeLoadException: 'Method 'Create' in type
'Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerSqlTranslatingExpressionVisitorFactory'
from assembly 'Microsoft.EntityFrameworkCore.SqlServer,
Version=3.1.10.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'
does not have an implementation.'
这是我的上下文
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
版本,请将所有软件包升级到最新的稳定版本。
我目前有一个 Razor 页面应用程序 (Core 3.1) 连接到 SQL 数据库,其上下文使用 IdentityDbContext。尝试在我的 Worker 服务中使用相同的上下文时,我继续收到此错误:
System.TypeLoadException: 'Method 'Create' in type 'Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerSqlTranslatingExpressionVisitorFactory' from assembly 'Microsoft.EntityFrameworkCore.SqlServer, Version=3.1.10.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' does not have an implementation.'
这是我的上下文
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
版本,请将所有软件包升级到最新的稳定版本。