0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[ASP.NET][EF6]EntityFramework6.Npgsql.dllがbinに配置されない

Last updated at Posted at 2021-09-28

環境・前提

  • ASP.NET MVC 5(Coreではない、.NET Framework)
  • VB.NET
  • Entity Framework 6 + EntityFramework6.Npgsql
  • NpgsqlはWeb.configで設定している。

ソリューション構成

Webプロジェクト(メインプロジェクト)
 ↓参照
BusinessLogicプロジェクト
 ↓参照
Entityプロジェクト
 ↓参照
EF6+Npgsql

障害内容

Webプロジェクトでは直接使用していないEF6+Npgsqlへの参照設定があった為、参照を削除したところ、ビルドは通るのに、MyDbContextクラスのコンストラクタでSystem.InvalidOperationException の実行時例外が発生するようになった。

発生した例外

System.InvalidOperationException: 'The Entity Framework provider type 'Npgsql.NpgsqlServices, EntityFramework6.Npgsql' registered in the application config file for the ADO.NET provider with invariant name 'Npgsql' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.'

発生箇所:

MyDbContext.vb
    Public Sub new()
        MyBase.New("name=MyDbContext") 'ここで例外発生
    End Sub

原因および検討事項

  • EntityFramework6.Npgsql.dllがASP.NETサイトのbinフォルダに配置されなくなっている。
  • EntityFramework6.Npgsqlの機能はソースコード上から直接参照するものではなく、Web.configで動的にロードされるものである為、コンパイラがDLLの必要性を判別できず、配置されなかったものと思われる。
  • EntityプロジェクトへのEntityFramework6.Npgsql.dllへの参照追加設定はしてあり、ローカルコピー設定もTrueになっているが、それでもbinフォルダに配置されていない。
  • Webプロジェクト(メインプロジェクト)へEntityFramework6.Npgsql.dllの参照設定を行えば強制的にbinフォルダにコピーされる模様。
  • しかし、WebプロジェクトではEF6は使っていないし、使わせたくもないので、ここへ参照設定を追加するのは避けたい。

解決策

  • ソースコード上でEntityFramework6.Npgsql.dllへの参照がハードコーディングされていれば、コンパイラが依存関係を認識してくれるはず。
  • 現状、EntityFramework6.Npgsql.dllに最も近いのはEntityプロジェクトなので、そこに上記のダミーコードを挿入すれば良い。
  • 本音を言うと、Entityプロジェクト自体も表向きNpgsqlに依存しているわけではない(データプロバイダとしてEF6が背後で動的ロードしているだけ)なので、ここにそんなダミーコードを追加するのも嫌だが、Webプロジェクトに無意味な参照が追加されるよりはマシと判断。

以下のファイルをEntityプロジェクトに追加した。

ResolveReferenceToEF6Npgsql.vb
Module ResolveReferenceToEF6Npgsql
    '意味のないコードだが、これを書かないと、コード上に参照がない為DLLがASP.NET環境に配置されない。
    Private __hack As Boolean = Npgsql.NpgsqlServices.Instance IsNot Nothing
End Module

C#だとこんな感じになると思われる。

ResolveReferenceToEF6Npgsql.cs
class ResolveReferenceToEF6Npgsql {
    // 意味のないコードだが、これを書かないと、コード上に参照がない為DLLがASP.NET環境に配置されない。
    private static bool __hack = (Npgsql.NpgsqlServices.Instance != null);
}

結果

WebプロジェクトからEF6+Npgsqlへの参照設定も問題なく削除し、正しく動作することを確認した。

本当は、プロジェクト設定に「このDLLに依存しているので、公開時に絶対に一緒に配置する」というオプションがあればよいと思うが、そういう設定を見つけられなかった。

試したけどダメだったもの一覧。

  1. Web.configのsystem.web - compilation - assemblies - add に EntityFramework6.Npgsqlを追加
  2. Web.configのruntime - assemblyBinding - dependentAssembly に EntityFramework6.Npgsql を追加
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?