0

Je suis en train de mettre en place une application Web basée sur ASP MVC 5 et Entity Framework 6. La solution est organisée avec Areas (une seule maintenant ...) et chaque Area a sa propre DBContext. Voir Picture o the solution.migrations framework framework entité ConnectionStringName surchargé par DBContext base

Dans le DBContext, j'ai défini un nom de chaîne de connexion affecté au contexte au moment de l'exécution, car il dépend d'une variable de connexion.

using System.Web; 
using RMC.Areas.TimeSheet.Controllers; 

namespace RMC.Areas.TimeSheet.DAL 
{ 
    public class timeSheetContext : DbContext 
    { 
     public timeSheetContext() 
      : base("name=DBConn_Data." + RMC.Controllers.BaseController.applicationName + ".FLAT") 
     { 
      Database.SetInitializer(new MigrateDatabaseToLatestVersion<timeSheetContext, RMC.Areas.TimeSheet.Migrations.Configuration>(true)); 
     } 


     public DbSet<ts_activityProfile> activityProfile { get; set; }     // Profilo delle attività 
     public DbSet<ts_activityProfile_ML> activityProfile_ML { get; set; }   // Profilo delle attività 
     public DbSet<ts_activity> activity { get; set; }        // Attività 
etc... 

Lorsque je tente d'ajouter une migration ou de mettre à jour la base de données de la console, même si je spécifie la chaîne de connexion explicitement (et la chaîne de connexion existe dans la principale web.config!), Les essais de l'outil de migration pour le lire à partir de DBContext: base ... où le paramètre d'exécution n'est pas défini.

à savoir commande

Add-MigrationMig000 -StartUpProjectName "RMC" -ProjectName "RMC" -ConfigurationTypeName "RMC.Areas.TimeSheet.Migrations.Configuration" -ConnectionStringName "DBConn_Data.re.FLAT" -Verbose 

L'erreur que je reçois est:

No connection string named 'DBConn_Data..FLAT' could be found in the application config file. 

Il semble qu'il ignore le -ConnectionStringName passé. La seule façon de le faire était de commenter: base (...) définie.

Le nom -ConnectionStringName ne doit-il pas remplacer: base()? Comment puis-je le faire fonctionner?

Merci

EDIT Voici le BaseController

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Mvc; 

using System.Threading; 
using RMC.Helpers; 
using RMC.ViewModel; 
using RMC.Models; 
using RMC.ViewModel.navigation; 


using System.Web.Configuration; 


namespace RMC.Controllers 
{ 
    [Authorize] 
    public class BaseController : Controller 
    { 

     public static string applicationName = ""; 
     public static bool noValue = true; 
     public static mLog oLog = null; 
     public static string defaultCulture = "";  // Cultura di defautl del sistema impostata nel web.config 

     protected override void Initialize(System.Web.Routing.RequestContext requestContext) 
     { 
      base.Initialize(requestContext); 

      /* 20/02/2014 
      Inizializzo la variabile statica che contiene l'application name. 
      Viene utilizzata dal DBContext per trovare la connectionString corretta. 
      */ 
      applicationName = System.Web.HttpContext.Current.Items["ApplicationName"].ToString(); 
etc... 

EDIT2 Ce qui est drôle est que si je passe dans la commande un nom de chaîne de mauvaise connexion, il se plaint que la connexion n » T existe! Mauvaise commande

Update-Database -ConnectionStringName DBConn_Data.reXXX.FLAT -StartUpProjectName RMC -ProjectName RMC -ConfigurationTypeName RMC.Areas.TimeSheet.Migrations.Configuration -Verbose 

message Erreur

No connection string named 'DBConn_Data.reXXX.FLAT' could be found in the application config file. 
+0

Pourriez-vous fournir le code de votre 'RMC.Controllers.BaseController'? –

+0

Ceci est juste une supposition, mais si les migrations EF doivent instancier votre DbContext et passer la chaîne de connexion, il ne peut pas le faire avec votre configuration actuelle. Pouvez-vous essayer d'ajouter un constructeur qui accepte le nom de la chaîne de connexion et le passe au constructeur de base? –

+0

Voir edit: J'ai ajouté le début du contrôleur –

Répondre

0

Fo une raison inconnue RMC.Controllers.BaseController.applicationName votre variable est vide. C'est pourquoi vous avez le message d'exception.

Ma suggestion pour vous, essayez de déplacer cette variable dans un champ statique, par exemple:

public static class Settings { 
    public static string AppName = "MyApp"; 
} 

Et que vous pouvez l'utiliser dans votre contexte:

public timeSheetContext() 
     : base("name=DBConn_Data." + Settings.AppName + ".FLAT") 
    { 
     Database.SetInitializer(new MigrateDatabaseToLatestVersion<timeSheetContext, RMC.Areas.TimeSheet.Migrations.Configuration>(true)); 
    } 
+0

Salut, le RMC.Controllers.BaseController.applicationName est censé être vide à ce stade, car il est rempli uniquement au moment de l'exécution. Comme l'application est multi-DB (même structure, beaucoup de DB différents) elle est initialisée lors de la connexion de l'utilisateur. Mon point est de pouvoir appliquer des migrations manuelles fournissant les noms de chaînes de connexion un par un à partir de la console. –

0

Ok, j'ai fini avec une solution que je n'aime pas ... mais fonctionne. Je modifié le DBContext de cette manière

namespace RMC.Areas.TimeSheet.DAL 
{ 
    public class timeSheetContext : DbContext 
    { 
     /* Used from Package Manager Console during manual Migrations */ 
     public timeSheetContext() 
     { 
      Database.SetInitializer(new MigrateDatabaseToLatestVersion<timeSheetContext, RMC.Areas.TimeSheet.Migrations.Configuration>(true)); 
     } 

     /* Used by App. Must pass the application name every time !*/ 
     public timeSheetContext(string applicationName) 
      : base("name=DBConn_Data." + applicationName + ".FLAT") 
     { 
      Database.SetInitializer(new MigrateDatabaseToLatestVersion<timeSheetContext, RMC.Areas.TimeSheet.Migrations.Configuration>(true)); 
     } 

Alors, quand je lance la migration manuelle, le premier constructeur obtient utilisé (en passant le paramètre -ConnectionStringName ...) et Teh second s'utilisé dans l'application, mais je dois passez le nom d'application à chaque fois.

Si quelqu'un a une meilleure solution s'il vous plaît poster!