Asp.net-Core

類型的 DbContext 不能被池化,因為它沒有一個接受 DbContextOptions 類型的單個參數的公共建構子

  • August 21, 2017

我正在嘗試將我們目前的 .Net Core 應用程序從 1.1 升級到 2.0,並收到此執行時錯誤:“無法合併 ‘CoreContext’ 類型的 DbContext,因為它沒有一個接受 DbContextOptions 類型的單個參數的公共建構子” .

它是由使用新的 IServiceCollection.AddDbContextPool<> 函式引起的。當我使用 IServiceCollection.AddDbContext<> 它仍然有效。

這個應用程序是 DB-First,所以我使用“Scaffold-DbContext”生成我們所有的上下文。因此,以及注入其他服務的需要,我在每個上下文中都有一個擴展,如下所示:

public partial class CoreContext
{
   public CoreContext(
       DbContextOptions&lt;CoreContext&gt; options,
       IUserService userService,
       IAuditRepository auditRepository
       ) : base(options) {...}
}

每當我執行 Scaffold-DbContext 時,我只是從 CoreContext 中刪除自動生成的建構子,但即使我把它放在那裡,我仍然會收到這個錯誤。

public partial class CoreContext : DbContext
{
   public CoreContext(DbContextOptions&lt;CoreContext&gt; options) : base(options) {}
}

我已經將 Program.cs 更新為新樣式:

public class Program
{
   public static void Main(string[] args)
   {
       BuildWebHost(args).Run();
   }

   public static IWebHost BuildWebHost(string[] args) =&gt;
       WebHost.CreateDefaultBuilder(args)
               .UseKestrel()
               .UseContentRoot(Directory.GetCurrentDirectory())
               .UseIISIntegration()
               .UseStartup&lt;Startup&gt;()
               .Build();
}

Startup.cs 非常簡單:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
   ...
   services.AddDbContextPool&lt;CoreContext&gt;(options =&gt; options.UseSqlServer(absConnectionString));
   ...
}

如果有幫助,我正在使用 Autofac 進行 DI。現在,我將預設使用非池化替代方案,但利用此功能會很好。

使用 時DbContext Pooling,將保留派生 DbContext 類中您自己的狀態(例如私有欄位)。這意味著您的服務的生命週期是現在singleton。這就是為什麼你不應該在這裡有其他注入服務。但是可以通過這種方式查詢所需的服務:首先,我們應該使用UseInternalServiceProvideron 方法DbContextOptionsBuilder告訴 EF 為其服務使用哪個服務提供者。此服務提供者必須為 EF 和任何提供者配置所有服務。所以我們應該手動註冊 EF 服務:

services.AddEntityFrameworkSqlServer();

然後介紹應用程序的服務提供者,現在也包括 EF 服務:

services.AddDbContextPool&lt;ApplicationDbContext&gt;((serviceProvider, optionsBuilder) =&gt;
{
  optionsBuilder.UseSqlServer("...");
  optionsBuilder.UseInternalServiceProvider(serviceProvider);
});

之後定義這些命名空間:

using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.DependencyInjection;

現在您可以使用以下方法在 ApplicationDbContext 類中訪問應用程序中的註冊服務

var siteSettings = this.GetService&lt;IOptionsSnapshot&lt;SiteSettings&gt;();

要麼

var siteSettings = this.GetInfrastructure().GetRequiredService&lt;IOptionsSnapshot&lt;SiteSettings&gt;();

this是 DbContext 的目前實例。

引用自:https://stackoverflow.com/questions/45804470