質問: 私はASP.NET Core 1.1でWeb APIを構築しています。 私は構成、ユーザー、グループ(約25テーブル)などの構成項目のための共通の基本スキーマを持つ数多くの異なるデータベース(異なるシステム用)を持っています。私は、図に示すように、基本クラスから継承して、モデルの共有部分の非常に広範なEF構成を複製することを避けようとしています。 ![私のDbContext継承ツリー](https://i.stack.imgur.com/mE7SK.jpg) ただし、 `DbContextOptions`をコンストラクターにパラメーターとして渡すEntity Framework(EF)要件のため、これは機能しません。コンストラクターが呼び出されるリポジトリの型に`DerivedRepository`が一致する必要があります。このパラメータは、 `:base(param)`呼び出すことによってベースの`DbContext`渡されなければなりません。 したがって、InvestContextが`DbContextOptions`で初期化された`DbContextOptions` 、 `ConfigurationContext`コンストラクタへの呼び出しが必須ではなく`DbContextOptions`型のパラメータを受け取っているため、 `base(DbContextOptions)`を呼び出し、EFがエラーをスローします。 `DbContextOptions`ます。 DbContextのoptionsフィールドは次のように定義されているため ``` private readonly DbContextOptions _options; ``` 私はこれを回避する方法を見ることができません。 共有モデルを一度定義して複数回使用する最善の方法は何ですか?私はヘルパー関数を作成し、それが派生したすべてのコンテキストから呼び出すことができると思いますが、継承と同じくらいきれいではありません。
回答: これで、上の例のような`InvestContext`を使用して、継承階層を使用する方法でこれを動作させました。 前述のように、InvestContextクラスは`DbContextOptions`型のコンストラクタパラメータを受け取りますが、 `DbContextOptions`をそのベースに渡す必要があります。 私は、 `DbContextOptions`変数からconnectionstringを掘り起こし、必要な型のDbContextOptionsインスタンスを構築するメソッドを作成しました。 InvestContextは、このメソッドを使用して、base()を呼び出す前にoptionsパラメータを正しい型に変換します。 変換方法は次のようになります。 ``` protected static DbContextOptions ChangeOptionsType(DbContextOptions options) where T:DbContext { var sqlExt = options.Extensions.FirstOrDefault(e => e is SqlServerOptionsExtension); if (sqlExt == null) throw (new Exception("Failed to retrieve SQL connection string for base Context")); return new DbContextOptionsBuilder() .UseSqlServer(((SqlServerOptionsExtension)sqlExt).ConnectionString) .Options; } ``` InvestContextのコンストラクタ呼び出しは次のように変更されます。 ``` public InvestContext(DbContextOptions options):base(options) ``` これに: ``` public InvestContext(DbContextOptions options):base(ChangeOptionsType(options)) ``` これまでのところ、InvestContextとConfigurationContextの両方が簡単なクエリで動作しますが、ハックのように思えますし、EF7の設計者が心に留めていたものではないかもしれません。 私はまだ複雑なクエリ、更新などを試みるとEFが結び目になると懸念して*いますが、これは問題ではないようです(下記参照)* **編集:**私はここでEF7チームの問題としてこの問題を記録しました。チームメンバーはEFコアコアの変更を次のように提案しました。 > "TContextを現在のコンテキストタイプから派生した型にするためのチェックを更新する必要があります" > > これは問題を解決するだろう。 そのチームメンバー(これについては問題がわかります)とのやりとりやEFコアコードの掘り下げが行われた後、上記で概説したアプローチは安全であり、提案された変更が実装されるまでは最良のアプローチです。