EF Core(Entity Framework Core)與SQLite的遷移,以及SQlite在EF中的侷限性及其解決方案

建立遷移

使用包管理控制檯

Add-Migration 遷移名稱

(比如 Add-Migration DatabaseInformation_Extension)

如果產生衝突可以使用:

Update-Database -Migration:0 (刪除表結構)

在Program處,服務啓動之前添加調用函數

private static void CreateDbIfNotExists(IHost host)
{
	using var scope = host.Services.CreateScope();
	var services = scope.ServiceProvider;
	using var context = scope.ServiceProvider.GetRequiredService<BeeNetContext>();
	context.Database.Migrate();
}

服務器啓動時候會自動完成遷移。

SQLite - SQLite 侷限性 - 《微軟 EntityFrameworkCore 中文文檔》 - 書棧網 · BookStack
https://www.bookstack.cn/read/Microsoft.EntityFrameworkCore.Docs.zh-Hans/7%E3%80%81%E6%95%B0%E6%8D%AE%E5%BA%93%E6%8F%90%E4%BE%9B%E7%A8%8B%E5%BA%8F-C%E3%80%81SQLite-B%E3%80%81SQLite%E5%B1%80%E9%99%90%E6%80%A7.md

關於SQLite不支持遷移的問題可以查看一下:

// UNDONE: Not supported by SQLite
//migrationBuilder.AlterColumn<string>(
//    name: "Title",
//    table: "Posts",
//    nullable: false,
//    oldClrType: typeof(string),
//    oldType: "TEXT",
//    oldNullable: true);

// Create a new table with the desired schema
// TODO: Randomize the name to avoid conflicts
migrationBuilder.CreateTable(
    name: "new_Posts",
    columns: table => new
    {
        Id = table.Column<int>(nullable: false)
            .Annotation("Sqlite:Autoincrement", true),
        Title = table.Column<string>(nullable: false)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_Posts", x => x.Id);
    });

// Copy data from the old table. Use NULLIF to specify a default value for newly
// required columns
migrationBuilder.Sql(@"
    INSERT INTO new_Posts (Id, Title)
    SELECT Id, IFNULL(Title, '')
    FROM Posts;
");

// Suspend foreign key enforcement during the swap
// TODO: Can't do this on SQL Server. Would need to rebuild referencing foreign
// keys there. But do we even need table rebuilds on SQL Server? Changing
// IDENTITY only requires a column rebuild
// NB: This commits the current transaction. We can't rollback the migration if
// anything after this fails. Maybe we can turn this off before the migration
// and somehow use PRAGMA foreign_key_check. Otherwise, we can mitigate it by
// doing rebuilds as late as possible
migrationBuilder.Sql("PRAGMA foreign_keys = 0;", suppressTransaction: true);

// Swap in the new table
migrationBuilder.DropTable(
    name: "Posts");
migrationBuilder.RenameTable(
    name: "new_Posts",
    newName: "Posts");

// TODO: We shouldn't do this if foreign key enforcement was off to begin with.
// There's no way to handle this in SQL, so we probably need a way to configure
// this. Maybe we can do this as a post migration step--the migration wouldn't
// fail, but you'd at least get an error if you compromised referential
// integrity
migrationBuilder.Sql("PRAGMA foreign_keys = 1;", suppressTransaction: true);

// Rebuild any indexes
migrationBuilder.CreateIndex(
    name: "IX_Posts_Title",
    table: "Posts",
    column: "Title");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章