ASP.NET Core1.1でWebAPIを構築しています。
構成、ユーザー、グループ(全部で約25のテーブル)などの構成アイテムの共通の基本スキーマを持つ、(システムごとに)さまざまなデータベースがあります。図に示すように、基本クラスから継承することで、モデルの共有部分の非常に広範なEF構成の重複を回避しようとしています。
ただし、これはDbContextOptions<DerivedRepository>
、コンストラクターにパラメーターとして渡すEntity Framework(EF)要件のため、機能しDerivedRepository
ません。コンストラクターが呼び出されるリポジトリーのタイプと一致する必要があります。次にDbContext
、を呼び出してパラメータをベースに渡す必要があります:base(param)
。
したがって、(たとえば)InvestContextがで初期化されるとDbContextOptions<InvestContext>
、コンストラクターbase(DbContextOptions<InvestContext>)
への呼び出しが必要な型ではなくConfigurationContext
型のパラメーターを受け取っているため、InvestContextが呼び出され、EFがエラーをスローします。DbContextのオプションフィールドは次のように定義されているためDbContextOptions<InvestContext>
DbContextOptions<ConfigurationContext>
private readonly DbContextOptions _options;
これを回避する方法がわかりません。
共有モデルを1回定義し、それを複数回使用するための最良の方法は何ですか?ヘルパー関数を作成して、派生したすべてのコンテキストから呼び出すことができると思いますが、継承ほどクリーンでも透過的でもありません。
OK、私はこれを次のように継承階層を使用する方法で機能させました(InvestContext
例として上から使用):
前述のように、InvestContextクラスは、型のコンストラクターパラメーターを受け取りますがDbContextOptions<InvestContext>
、そのDbContextOptions<ConfigurationContext>
ベースに渡す必要があります。
DbContextOptions
変数から接続文字列を掘り出し、必要なタイプのDbContextOptionsインスタンスを構築するメソッドを作成しました。InvestContextは、base()を呼び出す前に、このメソッドを使用して、オプションパラメーターを適切なタイプに変換します。
変換方法は次のようになります。
protected static DbContextOptions<T> ChangeOptionsType<T>(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<T>()
.UseSqlServer(((SqlServerOptionsExtension)sqlExt).ConnectionString)
.Options;
}
InvestContextコンストラクター呼び出しはこれから変更されます。
public InvestContext(DbContextOptions<InvestContext> options):base(options)
これに:
public InvestContext(DbContextOptions<InvestContext> options):base(ChangeOptionsType<ConfigurationContext>(options))
これまでのところ、InvestContextとConfigurationContextはどちらも単純なクエリで機能しますが、ちょっとしたハックのようで、EF7の設計者が考えていたものではない可能性があります。
複雑なクエリや更新などを試してみると、EFが結び目になるのではないかと心配しています。これは問題ではないようです。以下を参照してください)
編集:私はこの問題をEF7チームの問題としてここに記録しました。チームメンバーは、次のようにEFコアコアへの変更を提案しました。
「TContextが現在のコンテキストタイプから派生したタイプになるようにチェックを更新する必要があります」
これで問題は解決します。
そのチームメンバー(この問題で確認できます)とさらに対話し、EFコアコードを掘り下げた後、上記で概説したアプローチは安全であり、提案された変更が実装されるまで最良のアプローチに見えます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加