Database.Migrate() 创建数据库但不创建表,EF 和 .NET Core 2
Database.Migrate() creating database but not tables, EF & .NET Core 2
这个问题已经被问过几次了,但是 solutions/documentation 中的 none 对我有用。
场景 - 我需要从头开始构建一个数据库并通过代码迁移对其进行编辑,根据文档,下面的行应该从 DbContext/ModelBuilder.
创建数据库
_dbContext.Database.Migrate();
然而,这只是创建数据库本身和表的 none。如果我 运行 下面的,
_dbContext.Database.EnsureCreated();
数据库和所有表都已创建,但是这不是一个选项,因为我需要进一步编辑迁移。我在 Migrate 行之后直接尝试了下面的代码,但 pendingMigrations 始终为 0。
var pendingMigrations = _dbContext.Database.GetAppliedMigrations().ToList();
if (pendingMigrations.Any())
{
var migrator = _dbContext.Database.GetService<IMigrator>();
foreach (var targetMigration in pendingMigrations)
migrator.Migrate(targetMigration);
}
我在这里遗漏了什么吗? Database.Migrate() 不应该像创建数据库一样创建表吗?
注意 - 在测试中,我在尝试另一种方法之前删除了数据库。
另一个经典案例,就是在此处发布问题后半小时才找到答案,苦苦挣扎了一两天。发布我的解决方案以防其他人遇到类似问题。
TLDR - _dbContext.Database.Migrate();
不创建迁移。
基本上,dbContext.Database.EnsureCreated()
不关心迁移,这就是它生成完整数据库 inc 表的原因(但是当然你不能迁移)。
_dbContext.Database.Migrate();
应用迁移并创建数据库(如果不存在)但是如果没有迁移则不会创建表。
基本上我有一个项目作为资源,我试图从用户生成的新应用程序中复制项目,但因为我从来没有 运行 资源项目中的任何迁移,所以没有任何东西可以迁移。 运行 资源项目 PMC 中的 Add-Migration Initial
为项目提供了初始迁移文件,因此当我 运行 在新数据库上迁移时,它知道要创建哪些表。
在我的例子中,我有多个项目并且 DesignTimeDbContextFactory
指向一个
MigrationsAssembly
但在启动时 sqlOptions
不是。
所以当 DI 创建时 DbContext
它不知道有待处理的迁移。
您可以使用以下方法检查待处理的迁移
dbContext.Database.GetPendingMigrations();
在 Migrate();
之前检查它是否找到迁移
解决方案是在 sqlOptions
中添加迁移 MigrationsAssembly
services.AddDbContext<BM_OCR_DbContext>(options =>
{
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection"),
sqlServer => sqlServer.MigrationsAssembly("BM.OCR.Server"));
});
另一种方法 - 在 EF 迁移项目中创建扩展方法。它可以在没有 sqlServer.MigrationsAssembly() 方法的情况下工作。
namespace Project.Data;
{
public static class Extensions
{
public static void AddEntityFramework(this IServiceCollection services, IConfiguration configuration)
{
var cnn = configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<AppDbContext>(opt => opt.UseSqlServer(cnn));
}
}
}
然后在Startup.cs中使用它
services.AddEntityFramework(Configuration);
这个问题已经被问过几次了,但是 solutions/documentation 中的 none 对我有用。
场景 - 我需要从头开始构建一个数据库并通过代码迁移对其进行编辑,根据文档,下面的行应该从 DbContext/ModelBuilder.
创建数据库_dbContext.Database.Migrate();
然而,这只是创建数据库本身和表的 none。如果我 运行 下面的,
_dbContext.Database.EnsureCreated();
数据库和所有表都已创建,但是这不是一个选项,因为我需要进一步编辑迁移。我在 Migrate 行之后直接尝试了下面的代码,但 pendingMigrations 始终为 0。
var pendingMigrations = _dbContext.Database.GetAppliedMigrations().ToList();
if (pendingMigrations.Any())
{
var migrator = _dbContext.Database.GetService<IMigrator>();
foreach (var targetMigration in pendingMigrations)
migrator.Migrate(targetMigration);
}
我在这里遗漏了什么吗? Database.Migrate() 不应该像创建数据库一样创建表吗?
注意 - 在测试中,我在尝试另一种方法之前删除了数据库。
另一个经典案例,就是在此处发布问题后半小时才找到答案,苦苦挣扎了一两天。发布我的解决方案以防其他人遇到类似问题。
TLDR - _dbContext.Database.Migrate();
不创建迁移。
基本上,dbContext.Database.EnsureCreated()
不关心迁移,这就是它生成完整数据库 inc 表的原因(但是当然你不能迁移)。
_dbContext.Database.Migrate();
应用迁移并创建数据库(如果不存在)但是如果没有迁移则不会创建表。
基本上我有一个项目作为资源,我试图从用户生成的新应用程序中复制项目,但因为我从来没有 运行 资源项目中的任何迁移,所以没有任何东西可以迁移。 运行 资源项目 PMC 中的 Add-Migration Initial
为项目提供了初始迁移文件,因此当我 运行 在新数据库上迁移时,它知道要创建哪些表。
在我的例子中,我有多个项目并且 DesignTimeDbContextFactory
指向一个
MigrationsAssembly
但在启动时 sqlOptions
不是。
所以当 DI 创建时 DbContext
它不知道有待处理的迁移。
您可以使用以下方法检查待处理的迁移
dbContext.Database.GetPendingMigrations();
在 Migrate();
之前检查它是否找到迁移
解决方案是在 sqlOptions
MigrationsAssembly
services.AddDbContext<BM_OCR_DbContext>(options =>
{
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection"),
sqlServer => sqlServer.MigrationsAssembly("BM.OCR.Server"));
});
另一种方法 - 在 EF 迁移项目中创建扩展方法。它可以在没有 sqlServer.MigrationsAssembly() 方法的情况下工作。
namespace Project.Data;
{
public static class Extensions
{
public static void AddEntityFramework(this IServiceCollection services, IConfiguration configuration)
{
var cnn = configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<AppDbContext>(opt => opt.UseSqlServer(cnn));
}
}
}
然后在Startup.cs中使用它
services.AddEntityFramework(Configuration);