Ef Core花里胡哨系列(7) 使用Ef Core也能维护表架构?

Ef Core花里胡哨系列(7) 使用Ef Core也能维护表架构?

我们这里指的并不是查询,而是利用Ef的迁移原理,生成可用的其它表架构操作的Sql。

例如你想在Ef Core里建表,并且可能程序里有多个provider,那么写Sql将是一件痛苦的事情,我们就是利用Ef Core迁移时的操作,来为我们所用。

如果看过此系列中屏蔽外键的那一篇博客,我们的主角就暗藏在里面,它就是各种Operation。

Operation

Ef Core中所有的迁移的工作单元均由Operation组成,例如CreateTableOperation、AlterColumnOperation等等,我们要做的就是将我们的操作组装为对应的Operation来模拟迁移的操作,让Ef Core去生成Sql,那我们在一定程度上就避免了Sql的强耦合,生成Sql将有Ef Core的提供程序来提供支持。

当然我们之前提到过,不同的提供程序可能有些实现是没有的,例如微软官方就不提供AlterColumnOperation,直接采用的暴力的Drop和Add,我们只需重写IMigrationsSqlGenerator中对应的实现即可。

使用Operation有两种方法实现:

  • 直接拼接Operation
  • 类似于迁移文件的写法

直接拼接Operation

直接拼接Operation需要我们创建对应的Operation并且填充里面的主要信息,生成Sql时,需要拿到DbContext内部的IMigrationsSqlGenerator作为服务,用于生成Sql。

csharp 复制代码
var service = CreateDbContext<DataDbContext>().GetService<IMigrationsSqlGenerator>();

var creator = new CreateTableOperation()
{
    Name = "test",
};
creator.Columns.Add(new AddColumnOperation()
{
    Name = "Id",
    ClrType = typeof(int),
    IsNullable = false
});

var operations = new List<MigrationOperation> {
    creator
};

var cmd = service.Generate(operations);

foreach (var item in cmd.Select(x => x.CommandText))
{
    TestOutputHelper.WriteLine(item);
}

类似于迁移文件的写法

类似于迁移文件的写法实现时,和迁移文件中展现的部分基本一样,生成Sql时,需要构建一个MigrationBuilder并且提供你要使用的Ef Core提供程序,项目里需要引用该提供程序 。随后即可生成对应的Sql。

csharp 复制代码
MigrationBuilder t = new MigrationBuilder("Microsoft.EntityFrameworkCore.SqlServer");

t.CreateTable(
        name: "flow_draft",
        columns: table => new
        {
            ID = table.Column<string>(type: "varchar(36)", maxLength: 36, nullable: false),
            FlowId = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false, comment: "流程Id"),
            UserId = table.Column<string>(type: "varchar(255)", nullable: false, comment: "草稿提交人"),
            FormDataId = table.Column<string>(type: "varchar(36)", maxLength: 36, nullable: false, comment: "数据Id"),
            Content = table.Column<string>(type: "longtext", nullable: false, comment: "表单冗余数据")
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_flow_draft", x => x.ID);
        },
        comment: "流程草稿记录")
    .Annotation("MySQL:Charset", "utf8mb4");

cmd = service.Generate(t.Operations);

foreach (var item in cmd.Select(x => x.CommandText))
{
    TestOutputHelper.WriteLine(item);
}
相关推荐
可乐ea4 小时前
Agent 评测换判据:用终态数据库状态判定任务是否完成
数据库·ui·oracle·mcp工具·agent评测·终态断言·智能体可靠性
l1t4 小时前
DeepSeek总结的一个不含数据的 DuckDB 数据库
服务器·数据库·duckdb
PaperData5 小时前
2007-2020年税收调查面板数据
数据库
程序员清风5 小时前
CSV、Excel 与数据库数据读取实践
数据库·oracle·excel
GEO实战经验分享5 小时前
GEO技术与工具全景:从监测仪表盘到Schema的实战指南
数据库
一个天蝎座的程序猿5 小时前
IoTDB集群扩容:从慌乱到从容的经验分享
数据库
用户788477316346 小时前
门店核销闭环:小程序扫码 + .NET 幂等接口 + WPF 看板,一天能跑通
微信小程序·c#
小小龙学IT6 小时前
Python SQLAlchemy 2.0 深度解析:从 Core 到 ORM 的数据访问双引擎
开发语言·数据库·python
DongQiShanRen7 小时前
裁决台账双向互校(上):名册与实物的第一道对账
java·linux·运维·数据库·人工智能·自然语言处理·数据挖掘
ShineWinsu7 小时前
对于Redis:AOF持久化的解析
linux·数据库·redis·缓存·面试·持久化·aof