web-dev-qa-db-ja.com

Database.SetInitializerを配置する場所

私は最終的に複数のUIバージョン/バリアントを作成できるプロジェクトに取り組んでいますが、これまでのところ、ソリューションWebにASP.NET MVCとのWebインターフェイスを含む2つのサブプロジェクトがあります。サービスプロジェクトは、データベースコンテキストとモデルが定義されている場所です。

私の目標は、私のWebプロジェクトでEF固有のコードへの参照を最小限にするか、場合によってはまったく持たないことです。私はそれを独立させたいので、サービスバックエンドでDLLを切り替えるとき(たとえばSQLからXMLまたはMySQLに)、MVCプロジェクトで複数の変更を行うべきではありません。

これはどのように見えるかです:

Project layout

私の質問は:-今のところ、Global.asax以外の場所でDatabase.SetInitializerを使用した例は見つかりませんでした。ファクトリーに似たDatabaseContextProviderクラスまたはコンテキストからデータを引き出してDTOでUIに提供するサービスクラスでモデルが変更された場合、データベースを再作成します。その場所の短所はありますか? -コンテキストのconnectionStringをProperties/Settings.settingsファイルで構成可能にしたい-それは合理的ですか?

31
torm

DbContextを最初に使用する前に、Database.SetInitializerメソッドを呼び出すメカニズムが必要です。そのため、通常Global.asaxファイルで呼び出されます。

tm.Serviceプロジェクトで初期化メソッドを使用してクラスを作成し、Application_Startメソッドで呼び出して、その初期化メソッドにDatabase.SetInitializerを配置できます。

設定ファイルから接続文字列を提供しても問題ありません。

14
Eranga

カップリングを回避するために、DataContextを含むアセンブリの外部に初期化子を設定しないことをお勧めします。そこで、DataContextの静的コンストラクターを追加しました。このように、このアセンブリを参照するすべてのプロジェクトは、明示的に設定せずにイニシャライザーを使用し、イニシャライザーはプロセスごとに1回だけ設定されます。

static MyDataContext()
{
   Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDataContext, Configuration>());
}

接続文字列は、もちろんアプリケーション構成ファイルから取得されます。

36
RonyK

DbContextコンストラクターに配置し、私のために働きます。

public myDbContext() : base(connectionToDatabase) {
        Database.SetInitializer<myDbContext>(null);
    }

上記のソリューションは機能しますが、次のコードほど効率的ではありません。

  protected void Application_Start()
    {
        Database.SetInitializer<myDbContext>(null);
    }

私の場合、UIにDALの参照がなく、そのためにEntityFramework構成を作成し、リフレクションを使用して設定を登録します。

 protected void Application_Start()
    {           
        EntityFrameworkConfig.RegisterSettings();
    }


 public static class EntityFrameworkConfig
{
    public static void RegisterSettings()
    {
        // Use the file name to load the Assembly into the current
        // application domain.
        Assembly a = Assembly.Load("MyAssembly");
        // Get the type to use.
        Type myType = a.GetType("MyType");
        // Get the method to call.
        MethodInfo myMethod = myType.GetMethod("MySettingsMethod");
        // Create an instance.
        object obj = Activator.CreateInstance(MyType);
        // Execute the method.
        myMethod.Invoke(obj, null);
    }
}

  public void Configurations()
    {
      //Other settings
        Database.SetInitializer<myDbContext>(null);
    }

更新済み

Entity Framework 6では、NullDatabaseInitializerを使用できるようになりました

Database.SetInitializer(new NullDatabaseInitializer<MyDbContext>());
9
Ricardo Huertas

Microsoftは、EF6以降、アプリケーションの構成ファイル内のデータベースコンテキストごとに1つの初期化子を構成できるようにしました。このMicrosoftページの最後のセクションを参照してください。 https://msdn.Microsoft.com/en-us/data/jj556606.aspx

これは、「Global.asax」アプローチと同様に、次のような利点があります。単体テストプロジェクトでは、同じデータベースコンテキストに対して異なる初期化子を使用できます。

3

[Global.asax]ページをクリックすると、Application_Start()メソッドが見つかります。このメソッドの内側で次のコードを過ぎます。このコードをサポートするには、System.Data.Entityを使用して名前空間を使用します。

Database.SetInitializer<namespace.modelclass>(null);
0
user9542003