c# - 处理 SQLite EF Core 限制 - 基础操作
问题描述
根据文档,EF Core SQLite 不支持使用迁移进行数据库开发的一些基本操作(例如删除列、设置外键等)。那么如何执行简单的数据库结构更改,例如删除列而不丢失数据并保持快照模型与数据库同步(没有脚手架)?
值得付出努力还是应该先使用数据库并为模型使用脚手架命令更新?如果我不能在迁移中执行所有必要的操作来更新我的数据库,那么我就不能利用迁移的好处来恢复我的数据库结构。那么在 EF-Core-Sqlite 中使用迁移的优势在哪里?ORM 应该让工作停止,而不是让工作变得更加困难。
解决方案
更新
Sqlite 迁移:表重建现在可在 EF Core 5 上使用。
原始答案
如何执行简单的数据库结构更改,例如删除列而不丢失数据并保持快照模型与数据库同步(没有脚手架)?
主要思想在EF Core 文档中进行了描述:迁移限制解决方法
您可以通过在迁移中手动编写代码来重建表来绕过其中的一些限制。表重建包括重命名现有表、创建新表、将数据复制到新表以及删除旧表。
例如我们用下Blog
表创建了一个数据库
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Foo { get; set; }
}
...然后我们要删除Foo
.
为此,请删除Blog.Foo
上面显示的类属性。
然后添加一个迁移来生成一个Migration
类。
由于MigrationBuilder.DropColumn
SQLite 不支持,我们应该Up
按照文档中的描述修改迁移方法。
protected override void Up(MigrationBuilder migrationBuilder)
{
// Create temporary Blog table with new schema
migrationBuilder.CreateTable(
name: "Blog_temp_new",
columns: table => new
{
BlogId = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Blog", x => x.BlogId);
});
// Copy Blog to Blog_temp_new
migrationBuilder.Sql("INSERT INTO Blog_temp_new (BlogId, Name) SELECT BlogId, Name FROM Blog;");
// Delete Blog
migrationBuilder.DropTable("Blog");
// Rename Blog_temp_new to Blog
migrationBuilder.RenameTable("Blog_temp_new", newName: "Blog");
}
所有Blog
数据及其BlogId
和Name
将在调用时保留Database.Migrate
。
我建议您在一个新项目上尝试这个,使用像Blog
示例这样的简单类。如果您的表有约束或索引,您还需要做其他事情。但是,如果您在一个简单的沙箱中进行试验,而不是试图在您的主项目中修复它,您应该能够轻松地学习如何处理这些问题。
是否值得努力
根据我的经验,是的!与 Database-First 相比,我发现 Model-First 更易于使用。我更喜欢尽可能用 C# 做所有事情,但如果您是 SQL 专家,那么您可能会有与我不同的观点。:)
推荐阅读
- python - 如何修复 GBTclassifier 混淆矩阵中的 Keyerror
- webpack - TypeError:无法读取未定义的属性“tapPromise”
- python - 在 python 中从 git 安装库 - ImportError: Bad git executable
- architecture - 在 UML 组件图中重用子组件
- go - 将 int 或 float 分配给接口是否会在内部导致块分配?
- vue.js - 条纹 oAuth 令牌 URL 被阻止
- variables - 我应该在哪里写 Anylogic 中动态变量的 if 条件?
- string - 如何在批处理脚本中将字符串拆分为 3 个不同的字符串?
- wordpress - wp_logout_url() 不重定向用户
- python - Airflow 中的 BigQuery 运算符未将 sql 作为原始文件读取