好的,我自己已经设法找到了解决方案,对此我很满意。
首先,我将列出应用程序的结构。
我确实有一个名为AppServerSettingsContext 的DbContext,它在源代码中定义如下:
/// <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:
这是我需要执行两次的命令,每个上下文一次。
然后,在我的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 循环,它将根据数据库中的连接字符串创建一个上下文。那么对于这个上下文,数据库正在升级到最新版本。
这样做的好处是我使用的是代码优先的方法,并且所有数据库始终是最新版本。
这样做的一个缺点是所有模型都需要完全相同。