实体框架手动迁移ConnectionStringName被DBContext基重写

本文关键字:DBContext 重写 ConnectionStringName 迁移 框架 实体 | 更新日期: 2023-09-27 18:21:48

我正在实现一个基于ASP MVC 5和实体框架6的Web应用程序。解决方案由区域组织(目前只有一个…),每个区域都有自己的DBContext。请参阅解决方案的图片。

在DBContext中,我定义了一个在运行时分配给Context的连接字符串名称,因为它依赖于登录变量。

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...

当我尝试从控制台添加迁移或更新数据库时,即使我明确指定了连接字符串(并且连接字符串存在于mainweb.config中!),迁移工具也会尝试从DBContext:base。。。其中未定义运行时参数。

即命令

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

我得到的错误是:

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

它似乎忽略了传递的-ConnectionStringName。我工作的唯一方法就是评论定义的:base(…)。

-ConnectionStringName不应该重写:base()吗?我怎样才能让它工作?

感谢

编辑这是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...

编辑2有趣的是,如果我在命令中传递了一个错误的连接字符串名称,它会抱怨连接不存在!命令错误

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

错误消息

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

实体框架手动迁移ConnectionStringName被DBContext基重写

由于某种未知原因,RMC.Controllers.BaseController.applicationName变量为空。这就是您收到异常消息的原因。

我给你的建议是,试着在一些静态字段中移动这个变量,例如:

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

你可以在你的上下文中使用它:

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

好吧,我最终得到了一个我不喜欢的解决方案。。。但有效。我以这种方式修改了DBContext

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

因此,当我运行手动迁移时,会使用第一个构造函数(传递-ConnectionStringName参数…),在应用程序中会使用第二个构造函数,但每次都必须传递applicationName。

如果有人有更好的解决方案,请发帖!