mysql 数据迁移_EFcore+MySql 数据迁移的时候,怎么给表结构加注释?

前言:

CodeFirst运用的场景比较少,不代表CodeFirst不好,也不能和DbFirst去作比较,本来就是两个东西。

吐槽:

MySql.Data.EntityFrameworkCore 作为Oracle官方维护的组件,居然对EF很多API不支持或者无效,最后放弃使用,改用Pomelo.EntityFrameworkCore.MySql.Design,这是第三方维护的,支持比官方好得多啊。

搭建开始:

1、首先我们需要创建一个.NetCore 3.1的控制台项目,就叫CodeFirstDemo,并且引入以下组件。

    -Microsoft.EntityFrameworkCore.Tools 3.1.5

    -Pomelo.EntityFrameworkCore.MySql.Design 3.1.1 

2、确定好链接字符串,注意:CodeFirst的时候,可以不用创建数据库,程序会自动创建,我们只需要保证能链接到数据库服务就行。

 server=127.0.0.1;port=3306; user id=root; password=123456;database=test;

3、创建一个Models文件夹,编写我们自己的实体类 UserInfo.cs

 using System.ComponentModel.DataAnnotations;
namespace CodeFirstDemo.Models
{
    /// 
    /// 用户表
    /// 
    public class UserInfo
    {
        /// 
        ///用户ID
        /// 
        [Key]
        public string UserId { get; set; }
        /// 
        ///用户名
        /// 
        public string UserName { get; set; }
        /// 
        ///用户年龄
        /// 
        public int Age { get; set; }
    }
}

4、编写我们项目的Context文件,根目录创建也行,单独建个文件夹存放也行,我这里直接放根目录, 取名为TestContext.cs

using CodeFirstDemo.Models;
using Microsoft.EntityFrameworkCore;
namespace CodeFirstDemo
{
    public class TestContext : DbContext
    {
        /// 
        ///配置
        /// 
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseMySql("server=127.0.0.1;port=3306; user id=root; password=123456;database=test;");
        }
        /// 
        ///用户表对象
        /// 
        public DbSet UserInfo { get; set; }
        /// 
        ///实体对象的配置
        /// 
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity(entity =>
            {
                entity.HasComment("用户表");
                entity.Property(t => t.UserId).HasComment("用户ID");
                entity.Property(t => t.Age).HasComment("用户年龄");
                entity.Property(t => t.UserName).HasComment("用户名");
            });
        }
    }
}

注意看啊,表的备注和字段的备注是单独去设置的,而不是直接读取里面的内容,相当于注释咱们得再写一次,三个字段还好,100张表,每张表20个字段,可想这工作量,后面再说我们怎么解决的。

5、这个时候,我们可以将我们代码同步到数据库了。打开程序包管理控制台。

b3c6ea7a63e4d80722ceb78c314eb0d7.png

f8726eac60922f695e75d11c04c67a06.png

6、我们将在这里执行EF的数据迁移命令。先介绍一下有哪些命令。

>get-help entityframework

402701e01f9d0277b3ecb69f177b3dd2.png

可以看到有这么几个命令,不多,他们的作用也有介绍,我们只需要会用其中几个就行。常用的如下:

>Add-Migration [name]      //添加迁移文件/初始化
>Update-Database           //执行迁移 没有数据库会自动创建
>Drop-Database                //删库
>get-help entityframework    //获取帮助
>Script-Migration            //生成sql脚本,来手动迁移

7、我们添加迁移文件,这时候不会创建数据库,只是创建一个迁移文件。

>Add-Migration init      //添加迁移文件/初始化建库

e151cad4b8c88f66bfc41145788605d0.png

看到自动生成了Migrations文件夹,并在其中生成了几个文件,并且打开了其中的xxxxxxx_init.cs这个文件。

我们发现这个类其实是时间_[name]来命名的,并且其中记录了数据库这次的变化。

8、执行迁移,更新到数据库。

这里会自动为我们创建数据库。如果你自己手动创建了,可能会报错,因为里面缺了他自己的一张迁移记录表。所以如果要自己创建数据库,还得准备他迁移所需的表,索性就让他自动创建库了。

>Update-Database           //执行迁移 没有数据库会自动创建

70e70dca805e29d106d79a3e994fd637.png

这边看到已经执行完成,这次项目没有任何变化,变化在数据库那边,我们打开数据库软件,去看看。

8987fc38b091e8ea9ee1bc2f67999506.png

我们发现,多了个名为Test的数据库,并且里面有两张表,一个UserInfo是我们自己创建的,还有就是他自己的迁移历史表。

到这里一个完成的CodeFirst已经完成了。

9、如果我们改了数据库实体,增加了一个字段或者修改了字段,咋搞?

我们还是执行这两句命令就行了,只是添加迁移文件的时候,名称不能和之前重复即可。

>Add-Migration updateuserinfo      //添加迁移文件
>Update-Database           //执行迁移

10、如果你错误太多,或者迁移文件太多了,管理复杂,你可以用删除库,删除Migrations文件夹,再次初始化即可。

>Drop-Database                //删库
>Add-Migration init      //添加迁移文件
>Update-Database           //执行迁移

11、回到开头的问题,当我有100张表,每张表20个字段的时候,备注应该怎么加,总不能挨个字段手写吧。

我的解决方案如下:

根据项目的xml文件,来解析生成这段代码,让我们免于手写浪费时间,前提是你的summary注释写的有用。

12、生成xml

项目名称上右键-->属性-->生成-->XML文档文件,我把他放在了App_Data文件夹下,如果不改,则会生成到根目录下。

41167db1d2be2e083459175b0ceb86da.png

编译一下,看看是否生成xml文件。

361079df7756cc6871818d0c64dff263.png

没有问题,我们打开这个xml文件,看看里面什么结构。

b420f90b7eba38e20e36f046fadd467e.png

我们看下xml结构:

members-->member[name='T:CodeFirstDemo.Models.UserInfo']  这个节点下是用户表类注释。name属性是T开头的。
members-->member[name='P:CodeFirstDemo.TestContext.UserInfo']  这个节点下是我们Context的属性备注。name是P开头的。

这两个地方都可以得到表的名称或者备注。

再看字段的备注从哪里来。

members-->member[name='P:CodeFirstDemo.Models.UserInfo.UserId']  这个节点下是我们UserInfo类的属性备注。name是P开头的。

所以说,xml文件中有我们所需的所有信息,包括字段名称。我们来写个方法读取xml并生成下面这段代码。

modelBuilder.Entity(entity =>
{
    entity.HasComment("用户表");
    entity.Property(t => t.UserId).HasComment("用户ID");
    entity.Property(t => t.Age).HasComment("用户年龄");
    entity.Property(t => t.UserName).HasComment("用户名");
});

代码如下:我是写了个控制台程序专门来做这个事情,所以我把xml文件拷贝过去,再读取。

string xmlPath = $"CodeFirstDemo.xml";//xml路径
XmlDocument xml = new XmlDocument();
xml.Load(xmlPath);
StringBuilder sbr = new StringBuilder();
XmlNodeList nodeList = xml.SelectNodes("//member");
foreach (XmlNode item in nodeList)
{
    string name = item.Attributes["name"].Value;
    if (name.IndexOf("P:CodeFirstDemo.TestContext.") > -1)
    {
        string property = name.Substring(name.LastIndexOf(".") + 1);
        string txtstr = item.InnerText.Replace(" ", "").Replace("\r", "").Replace("\n", "");
        sbr.AppendLine($"modelBuilder.Entity(entity =>");
        sbr.AppendLine("{");
        sbr.AppendLine($"entity.HasComment(\"{txtstr}\");");
        foreach (XmlNode son in nodeList)
        {
            string sonname = son.Attributes["name"].Value;
            if (sonname.IndexOf($"P:CodeFirstDemo.Models.{property}.") > -1)
            {
                string sonproperty = sonname.Substring(sonname.LastIndexOf(".") + 1);
                string sontxtstr = son.InnerText
                    ?.Replace("\"", "\\\"")
                    ?.Replace(" ", "")
                    ?.Replace("\r", "")
                    ?.Replace("\n", "");
                if (sontxtstr.ToLower().IndexOf("[notmapped]") == -1)
                {
                    sbr.AppendLine($"entity.Property(t=>t.{sonproperty}).HasComment(\"{sontxtstr}\");");
                }
            }
        }
        sbr.AppendLine("});");
        sbr.AppendLine("");
    }
}
System.IO.File.WriteAllText("HasComment.txt", sbr.ToString());
Console.WriteLine(sbr);

执行之后,生成了txt文件

64a6d4c5cc7e703866d469d08e58728b.png

b6ab4a5410315a786f656539b34e39de.png

把txt里面的内容拷贝过去到TestContext.cs的OnModelCreating方法里面就可以了。

13e2d34ed07a9850eb9125c8df4e8445.png

CarsonIT微信扫码关注公众号

策略、创意、技术

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值