簡體   English   中英

如何通過代碼直接使用 EF Core Migrations API

[英]How can I use EF Core Migrations API directly by code

使用 Entity Framework Core,我們可以生成 C# 遷移文件,其中包含用於創建表、列、索引等的數據庫信息……然后我們可以使用命令行或使用 EF DbContext 部署數據庫。

有沒有辦法通過代碼直接使用 Migrations API 來修改數據庫,而不使用“真實”遷移(沒有代碼 model 或 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方法中添加什么來在我的數據庫中創建表?

我進入了 EF Core 內部,並找到了一種使用 API 的方法。

我不確定這是否是一個好主意,或者它是否可以正常工作,但它適用於一個簡單的案例(創建表,添加列)。

首先,我們需要注冊一些 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 特定的實現,我認為它可以與其他提供程序一起使用,但我沒有測試。

為了構建數據庫,我創建了一個遷移 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);
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM