web-dev-qa-db-fra.com

Place pour mettre Database.SetInitializer

Je travaille sur un projet qui peut aboutir à plusieurs versions/variantes d’interface utilisateur, mais jusqu’à présent, j’ai deux sous-projets dans ma solution, une interface Web contenant du Web avec ASP.NET MVC. Le projet de service est l'endroit où j'ai défini le contexte et les modèles de ma base de données. 

Mon objectif est d’avoir un minimum, voire aucune référence, de code spécifique à EF dans mon projet Web. Je veux qu'il soit indépendant. Ainsi, lorsque je commute les dll avec le service backend (de laisser SQL vers XML ou MySQL), je ne devrais pas effectuer plusieurs modifications dans mon projet MVC. 

Voici à quoi ça ressemble:

Project layout

Mes questions sont les suivantes: - Jusqu'à présent, je n'ai trouvé aucun exemple d'utilisation de Database.SetInitializer ailleurs que Global.asax. J'aimerais mettre la recréation de la base de données si le modèle change dans ma classe DatabaseContextProvider de type usine ou dans la classe de service qui extrait les données du contexte et les fournit à l'interface utilisateur avec les DTO. Y a-t-il des inconvénients à cet emplacement? - J'aimerais que la chaîne de connexion du contexte soit configurable avec le fichier Propriétés/Settings.settings - est-ce raisonnable?

31
torm

Vous auriez besoin d'un mécanisme pour appeler la méthode Database.SetInitializer avant la toute première utilisation de DbContext. C'est pourquoi il est généralement appelé dans le fichier Global.asax.

Vous pouvez créer une classe avec une méthode d'initialisation dans votre projet tm.Service et l'appeler dans la méthode Application_Start et y placer le Database.SetInitializer.

Son ok pour fournir la chaîne de connexion à partir d'un fichier de réglage.

14
Eranga

Pour éviter le couplage, je préférerais ne pas définir l’initialiseur en dehors de l’Assemblée contenant le DataContext. J'ai donc ajouté un constructeur statique pour le DataContext. De cette manière, chaque projet référençant cet assemblage bénéficiera de l'initialiseur sans le définir explicitement, et l'initialiseur n'est défini qu'une fois par processus.

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

La chaîne de connexion sera bien sûr extraite du fichier de configuration de l'application.

36
RonyK

Je l'ai mis sur le constructeur DbContext et travaille pour moi.

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

La solution ci-dessus fonctionnera, mais elle n’est pas aussi efficace que le code suivant:

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

Dans mon cas, je n'ai pas de référence de mon DAL sur l'interface utilisateur. C'est pourquoi j'ai créé une configuration EntityFramework et enregistré mon paramètre en utilisant une réflexion.

 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);
    }

Mis à jour

Avec Entity Framework 6, vous pouvez maintenant utiliser NullDatabaseInitializer

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

Microsoft a rendu possible, à partir de EF6, de configurer un initialiseur par contexte de base de données dans le fichier de configuration de l'application. Voir la dernière section de cette page Microsoft: https://msdn.Microsoft.com/en-us/data/jj556606.aspx

Cette approche, à l’instar de l’approche "Global.asax", présente l’avantage, par exemple: Les projets de test unitaire peuvent utiliser un initialiseur différent pour le même contexte de base de données.

3
Carsten Führmann

Cliquez sur la page Global.asax et vous trouverez une méthode Application_Start (). À l'intérieur de cette méthode, passez le code suivant. Pour prendre en charge ce code, utilisez un espace de noms utilisant System.Data.Entity;

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