好吧,我设法找到一个解决办法我自己,我与它很高兴。
首先,我将展示应用程序的结构。
我有一个DbContext
称为AppServerSettingsContext
这是在源代码中定义是这样的:
/// <summary>
/// Initializes a new instance of the <see cref="AppServerSettingsDataContext"/>.
/// </summary>
public AppServerSettingsDataContext()
: base("AppServerSettingsDataContext")
{ }
该上下文有2层不同的实体(一个用于一个构件,一个用于该特定部件的所有设置) 。
为了能够执行迁移,我需要在应用程序配置文件中有一个ConnectionString
,就像我们使用的方式一样。
然后,我有另一个名为AppServerDataContext
的上下文。 这有2个构造如下表现:
/// <summary>
/// Initializes a new instance of the <see cref="AppServerDataContext"/>.
/// </summary>
public AppServerDataContext() :
this(ConfigurationManager.ConnectionStrings["AppServer"].ConnectionString)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="AppServerDataContext"/>.
/// </summary>
/// <param name="connectionString">The full connection string which is used to connect to the database.</param>
public AppServerDataContext(string connectionString)
: base(connectionString) { }
你会在这我可以指定连接字符串或我加载应用程序配置文件中的连接字符串代码中看到。
你会明白为什么这很重要。
我有DbContext
指向配置文件中的连接字符串。这并不是必须的,但我习惯这样工作。因此只有在调用add-migration
命令时才会使用连接字符串。这是因为该命令需要数据库检查数据库的当前状态并添加正确的迁移。
现在,我正在使用2个上下文文件处理单个项目,因此NuGet程序包管理器控制台需要一种方法来识别此问题。
因此,下面的命令可以用来:
启用特定上下文迁移:
- `PM>启用的迁移-ContextTypeName:-MigrationsDirectory:
这是一个我需要执行两次的命令,每次执行一次XT。
然后,在我的AppServerSettings
上下文的Seed
方法,我会写下面的代码:
/// <summary>
/// Runs after upgrading to the latest migration to allow seed data to be updated.
/// </summary>
/// <param name="context">Context to be used for updating seed data.</param>
protected override void Seed(AppServerSettingsDataContext context)
{
// Creates the Member and assign all the settings which are required for the application to function.
context.Members.AddOrUpdate(x => x.Name, new Member("Povlo")
{
Settings = new List<MemberSettings>
{
new MemberSettings("DatabaseConnectionString", "Removed for Security Reasons"),
}
});
// Make sure that for every member, the database is created by using the "MigrateDatabaseToLatestVersion" migration.
foreach (var setting in context.Members.Select(member => member.Settings.FirstOrDefault(x => x.Key == "DatabaseConnectionString")))
{
using (var appServerContext = new AppServerDataContext(setting.Value))
{
var de = new MigrateDatabaseToLatestVersion<AppServerDataContext, AppServer.Configuration>();
de.InitializeDatabase(appServerContext);
appServerContext.Database.Initialize(true);
}
}
}
我在这里做的基本上都是第一次创建与给定的连接字符串的成员(也可以是多个)。
然后,在同样的方法中,我有一个foreach循环,它将根据数据库中的连接字符串创建一个上下文。然后在这种情况下,数据库正在升级到最新版本。
这样做的好处是我使用的是代码优先的方法,并且所有的数据库都是最新的版本。
这样做的缺点是所有模型都需要完全相同。
我会想到将数据库迁移到单独的进程,但不是在正常执行应用程序期间。这个过程可能需要独占访问数据库。 –
我正在处理某件事情,但这并不完全。也许你对如何用连接字符串而不是连接字符串名称来调用'Database.SetInitializer'有任何想法。 – Complexity
我想你可以用'DbConnection'参数构建'DbContext',你可以像你一样创建f.e.您可以将连接字符串传递给'SqlConnection'构造函数。 –