類型的 DbContext 不能被池化,因為它沒有一個接受 DbContextOptions 類型的單個參數的公共建構子
我正在嘗試將我們目前的 .Net Core 應用程序從 1.1 升級到 2.0,並收到此執行時錯誤:“無法合併 ‘CoreContext’ 類型的 DbContext,因為它沒有一個接受 DbContextOptions 類型的單個參數的公共建構子” .
它是由使用新的 IServiceCollection.AddDbContextPool<> 函式引起的。當我使用 IServiceCollection.AddDbContext<> 它仍然有效。
這個應用程序是 DB-First,所以我使用“Scaffold-DbContext”生成我們所有的上下文。因此,以及注入其他服務的需要,我在每個上下文中都有一個擴展,如下所示:
public partial class CoreContext { public CoreContext( DbContextOptions<CoreContext> options, IUserService userService, IAuditRepository auditRepository ) : base(options) {...} }每當我執行 Scaffold-DbContext 時,我只是從 CoreContext 中刪除自動生成的建構子,但即使我把它放在那裡,我仍然會收到這個錯誤。
public partial class CoreContext : DbContext { public CoreContext(DbContextOptions<CoreContext> options) : base(options) {} }我已經將 Program.cs 更新為新樣式:
public class Program { public static void Main(string[] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build(); }Startup.cs 非常簡單:
public IServiceProvider ConfigureServices(IServiceCollection services) { ... services.AddDbContextPool<CoreContext>(options => options.UseSqlServer(absConnectionString)); ... }如果有幫助,我正在使用 Autofac 進行 DI。現在,我將預設使用非池化替代方案,但利用此功能會很好。
使用 時
DbContext Pooling,將保留派生 DbContext 類中您自己的狀態(例如私有欄位)。這意味著您的服務的生命週期是現在singleton。這就是為什麼你不應該在這裡有其他注入服務。但是可以通過這種方式查詢所需的服務:首先,我們應該使用UseInternalServiceProvideron 方法DbContextOptionsBuilder告訴 EF 為其服務使用哪個服務提供者。此服務提供者必須為 EF 和任何提供者配置所有服務。所以我們應該手動註冊 EF 服務:services.AddEntityFrameworkSqlServer();然後介紹應用程序的服務提供者,現在也包括 EF 服務:
services.AddDbContextPool<ApplicationDbContext>((serviceProvider, optionsBuilder) => { optionsBuilder.UseSqlServer("..."); optionsBuilder.UseInternalServiceProvider(serviceProvider); });之後定義這些命名空間:
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection;現在您可以使用以下方法在 ApplicationDbContext 類中訪問應用程序中的註冊服務
var siteSettings = this.GetService<IOptionsSnapshot<SiteSettings>();要麼
var siteSettings = this.GetInfrastructure().GetRequiredService<IOptionsSnapshot<SiteSettings>();
this是 DbContext 的目前實例。