web.config で接続文字列を使用する代わりに、カスタム接続文字列を EF コンテキストに挿入したいと考えています。アイデアは、データベース関連のすべてのロジックを MVC プロジェクトから別のレイヤーに移動することです。また、Web アプリケーションではなく、このレイヤーが適切な接続文字列を担当するようにしたいと考えています。
現在コンテキストを使用しているサービスは、デフォルトのコンストラクターを呼び出しています。
using (var context = new MyDbContext()) {
//...
}
デフォルトのコンストラクターは、次DbContext
の接続文字列の名前で内部的に呼び出していますweb.config
。
public partial class MyDbContext : DbContext
{
public MyDbContext()
: base("name=MyDbContext")
{
}
//...
}
カスタム接続文字列を挿入するには、接続文字列を引数として受け取るオーバーロードされたコンストラクターが必要です。残念ながら、そのようなコンストラクタは提供されていません。
このクラスは自動生成され、すぐに上書きされるため、コンストラクターのオーバーロードをMyDbContext
クラス内に手動で追加することは非常に悪い考えであることは明らかです。これ以上これについて話すのはやめましょう、それは禁じられています。限目。
は部分クラスなのでMyDbContext
、別のクラス ファイルに追加のコンストラクタを追加することもできますpartial class MyDbContext
が、これも臭いようです。理由はわかりませんが、私の脳は悪い考えを言っています。
Model.Context.tt
調査の結果、C# といくつかのテンプレート マークアップを組み合わせた T4 テンプレートを編集することで、EF にこの追加のコンストラクターを含めるように指示できることがわかりました。元のコンストラクタは次のとおりです。
public <#=Code.Escape(container)#>()
: base("name=<#=container.Name#>")
{
<#
WriteLazyLoadingEnabled(container);
#>
}
同様のロジックを追加して、接続文字列を含むオーバーロードされたコンストラクターを生成するのは明らかに簡単です。
public <#=Code.Escape(container)#>(string nameOrConnectionString)
: base(nameOrConnectionString)
{
<#
WriteLazyLoadingEnabled(container);
#>
}
これを試してみたところ、モデル クラスの再生成と DB からのモデルの更新の両方が T4 テンプレートに影響しないため、追加のコンストラクターが常に存在することに気付きました。良い!一見、これは適切なソリューションのように見えますが...
そして、ここに私の質問があります:それは本当に良い解決策ですか?
3 つのオプションをもう一度比較してみましょう。
- 自動生成されたクラスを編集します (わかりました、これについては忘れることに同意しました)
- コンストラクターを部分クラス ファイルに追加する
- T4 テンプレートを編集して、追加のコンストラクターを生成するように EF に指示します。
これら 3 つのオプションのうち、3 番目のオプションが最も便利でクリーンなソリューションのように思えます。あなたの意見は何ですか?誰かが正当な理由を持っていますか、なぜこれが悪い考えになるのでしょうか? おそらくカスタムを使用して、接続文字列を挿入するためのオプションは他にありますconnectionFactory
か? もしそうなら、どうすればいいですか?