2017-08-21 7 views
1

現在の.Netコアアプリケーションを1.1から2.0にアップグレードしようとしています。型 'CoreContext'のDbContextは、DbContextOptions型の単一パラメータを受け入れる単一のパブリックコンストラクタを持たないためプールできません。DbContextOptions型の単一のパラメータを受け入れる単一のパブリックコンストラクタがないため、型のDbContextをプールできません。

これは、新しいIServiceCollection.AddDbContextPool <>関数を使用することによって発生します。 IServiceCollection.AddDbContext <を使用すると、それでも動作します。

このアプリケーションはDB-Firstであるため、Scaffold-DbContextを使用してすべてのコンテキストを生成します。その、と私はこのようなすべてのコンテキストの拡張子を持っている他のサービスを注入する必要性のために:私は足場-DbContextを実行するたびに

public partial class CoreContext 
{ 
    public CoreContext(
     DbContextOptions<CoreContext> options, 
     IUserService userService, 
     IAuditRepository auditRepository 
     ) : base(options) {...} 
} 

を私はちょうど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)); 
    ... 
} 

場合、私はDIのためAutofacを使用していますそれは助ける。今のところ、私はPooling以外の代替手段に戻すことにしますが、この機能を利用するといいでしょう。

+0

私は同じ問題があります。あなたはそれを回避する方法を発見しましたか、または非プールに戻っていますか?この新しい機能を使用できることは素晴らしいことでしょう。 – grokky

+0

私は非プールオプションに戻りました。まだそれを嘆く時間を持っていない、移動する必要があります。 –

答えて

1

AddDbContextPoolの代わりにAddDbContextを使用してみてください。これは同じ状況で私を助けました。 「それは型DbContextOptionsの単一のパラメータを受け入れ、単一のパブリックコンストラクタを持っていないため、」あなたは離れてDbContextOptionsを受け入れる1から任意のpublicコンストラクタを持っている場合は services.AddDbContext<CoreContext>(options => options.UseSqlServer(absConnectionString));

0

、あなたはそれらを削除するか、またはそれらを非ようにする必要がありコンテキストプーリングを使用するには、-publicを使用します。

また、OnConfiguringメソッドをオーバーライドすることによって何ができるかについては制限があります。 https://docs.microsoft.com/en-us/ef/core/what-is-new/index#dbcontext-pooling

3

DbContext Poolingを使用すると、派生したDbContextクラスの自分の状態(プライベートフィールドなど)は保持されますが、これはここのドキュメントで参照されています。つまり、あなたのサービスの生涯はsingletonになりました。だからあなたはここに他の注射サービスを用意すべきではありません。 このようにして、必要なサービスを照会することができます。 まずDbContextOptionsBuilderUseInternalServiceProviderメソッドを使用して、そのサービスに使用するサービスプロバイダーを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の現在のインスタンスです。

関連する問題