• 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

    var service = CreateDbContext().GetService();
    
    var creator = new CreateTableOperation()
    {
        Name = "test",
    };
    creator.Columns.Add(new AddColumnOperation()
    {
        Name = "Id",
        ClrType = typeof(int),
        IsNullable = false
    });
    
    var operations = new List {
        creator
    };
    
    var cmd = service.Generate(operations);
    
    foreach (var item in cmd.Select(x => x.CommandText))
    {
        TestOutputHelper.WriteLine(item);
    }
    

    类似于迁移文件的写法

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

    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);
    }
    
  • 相关阅读:
    oracle多变量批量造测试数据
    C++ 继承和派生
    基于SSM的旅游景点购票管理系统
    【Linux】LVM原理及核心概念
    循环单链表的头插及尾插实现
    SAD notes
    玩转双指针
    Photoshop图层混合模式公式(Unity,CG实现)
    企业全面管理解决方案:基于Java技术的ERP管理系统源码
    异步编程
  • 原文地址:https://www.cnblogs.com/donpangpang/p/17942407