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

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

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

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

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

Operation

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

当然我们之前提到过,不同的提供程序可能有些实现是没有的,例如微软官方就不提供AlterColumnOperation,直接采用的暴力的DropAdd,我们只需重写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);
}
相关推荐
NCIN EXPE3 小时前
redis 使用
数据库·redis·缓存
MongoDB 数据平台3 小时前
为编码代理引入 MongoDB 代理技能和插件
数据库·mongodb
极客on之路3 小时前
mysql explain type 各个字段解释
数据库·mysql
代码雕刻家4 小时前
MySQL与SQL Server的基本指令
数据库·mysql·sqlserver
lThE ANDE4 小时前
开启mysql的binlog日志
数据库·mysql
yejqvow124 小时前
CSS如何控制placeholder文字的颜色_使用--placeholder伪元素
jvm·数据库·python
oLLI PILO4 小时前
nacos2.3.0 接入pgsql或其他数据库
数据库
m0_743623924 小时前
HTML怎么创建多语言切换器_HTML语言选择下拉结构【指南】
jvm·数据库·python
pele4 小时前
Angular 表单中基于下拉选择动态启用字段必填校验的完整实现
jvm·数据库·python