如何通过代码直接使用 EF Core Migrations API
How can I use EF Core Migrations API directly by code
有了Entity Framework Core,我们可以生成C#迁移文件,包含数据库信息来创建tables、列、索引等...然后我们可以使用命令行部署数据库,或者使用 EF DbContext。
有没有办法通过代码直接使用迁移 API 来修改数据库,而不使用“真正的”迁移(没有代码模型或 dbContext)?
我想做这样的事情:
var builder = new MigrationBuilder(activeProvider);
builder.CreateTable(
name: "Table1",
columns: table => new
{
Id = table.Column<int>(nullable: false),
Name = table.Column<string>(maxLength: 256, nullable: true)
});
Apply(builder, connectionString);
我应该在 Apply
方法中输入什么来在我的数据库中创建 table?
我进入了 EF Core 内部,找到了使用 API 的方法。
我不确定这是否是个好主意,或者它是否可以正常工作,但它适用于一个简单的案例(创建 table,添加列)。
首先,我们需要注册一些 EF Core 服务:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ICurrentDbContext, CurrentDbContext>();
services.AddScoped<RelationalConnectionDependencies>();
services.AddEntityFrameworkSqlServer();
DbContextOptionsBuilder dbContextOptionsBuilder = new DbContextOptionsBuilder<DbContext>();
dbContextOptionsBuilder.UseSqlServer("Data Source=.\SQLEXPRESS;Initial Catalog=TestDeploy;Integrated Security=True;");
services.AddSingleton<IDbContextOptions>(dbContextOptionsBuilder.Options);
services.AddDbContext<DbContext>();
services.AddScoped<MyMigrationRunner>();
}
我们并没有直接使用DbContext,但好像是内部使用的。我们不需要任何特定的东西,我们只需从 EF Core 注册基础 DbContext。
此外,我使用了 SqlServer 特定实现,我认为它可以与其他提供程序一起使用,但我没有测试。
为了构建数据库,我创建了一个 Migration class
public class MyMigration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Table1",
columns: table => new
{
Id = table.Column<int>(nullable: false),
Name = table.Column<string>(maxLength: 256, nullable: true)
});
}
}
现在我可以使用 IMigrationsSqlGenerator
服务生成 SQL 命令并将它们应用于数据库
public class MyMigrationRunner
{
private readonly IRelationalConnection connection;
private readonly IMigrationsSqlGenerator migrationsSqlGenerator;
public MyMigrationRunner(IMigrationsSqlGenerator migrationsSqlGenerator, IRelationalConnection connection)
{
this.migrationsSqlGenerator = migrationsSqlGenerator;
this.connection = connection;
}
public void Run()
{
var migration = new MyMigration();
var commands = migrationsSqlGenerator.Generate(migration.UpOperations).ToList();
foreach (var cmd in commands)
{
cmd.ExecuteNonQuery(connection);
}
}
}
有了Entity Framework Core,我们可以生成C#迁移文件,包含数据库信息来创建tables、列、索引等...然后我们可以使用命令行部署数据库,或者使用 EF DbContext。
有没有办法通过代码直接使用迁移 API 来修改数据库,而不使用“真正的”迁移(没有代码模型或 dbContext)?
我想做这样的事情:
var builder = new MigrationBuilder(activeProvider);
builder.CreateTable(
name: "Table1",
columns: table => new
{
Id = table.Column<int>(nullable: false),
Name = table.Column<string>(maxLength: 256, nullable: true)
});
Apply(builder, connectionString);
我应该在 Apply
方法中输入什么来在我的数据库中创建 table?
我进入了 EF Core 内部,找到了使用 API 的方法。
我不确定这是否是个好主意,或者它是否可以正常工作,但它适用于一个简单的案例(创建 table,添加列)。
首先,我们需要注册一些 EF Core 服务:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<ICurrentDbContext, CurrentDbContext>();
services.AddScoped<RelationalConnectionDependencies>();
services.AddEntityFrameworkSqlServer();
DbContextOptionsBuilder dbContextOptionsBuilder = new DbContextOptionsBuilder<DbContext>();
dbContextOptionsBuilder.UseSqlServer("Data Source=.\SQLEXPRESS;Initial Catalog=TestDeploy;Integrated Security=True;");
services.AddSingleton<IDbContextOptions>(dbContextOptionsBuilder.Options);
services.AddDbContext<DbContext>();
services.AddScoped<MyMigrationRunner>();
}
我们并没有直接使用DbContext,但好像是内部使用的。我们不需要任何特定的东西,我们只需从 EF Core 注册基础 DbContext。
此外,我使用了 SqlServer 特定实现,我认为它可以与其他提供程序一起使用,但我没有测试。
为了构建数据库,我创建了一个 Migration class
public class MyMigration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Table1",
columns: table => new
{
Id = table.Column<int>(nullable: false),
Name = table.Column<string>(maxLength: 256, nullable: true)
});
}
}
现在我可以使用 IMigrationsSqlGenerator
服务生成 SQL 命令并将它们应用于数据库
public class MyMigrationRunner
{
private readonly IRelationalConnection connection;
private readonly IMigrationsSqlGenerator migrationsSqlGenerator;
public MyMigrationRunner(IMigrationsSqlGenerator migrationsSqlGenerator, IRelationalConnection connection)
{
this.migrationsSqlGenerator = migrationsSqlGenerator;
this.connection = connection;
}
public void Run()
{
var migration = new MyMigration();
var commands = migrationsSqlGenerator.Generate(migration.UpOperations).ToList();
foreach (var cmd in commands)
{
cmd.ExecuteNonQuery(connection);
}
}
}