Code Fisrt 更新注释到mysql数据库

背景:

从java项目翻到.net core 项目,将java的实体转换成.net 的实体,然后使用 ef tool 直接更新到数据库

命令如下:

Enable-Migrations -EnableAutomaticMigrations
Add-Migration InitialCreate
Update-Database -Verbose
 
更新的时候会遇到几个问题
1. 外键关系:
因为我的项目中使用Guid做关联,所有就没有使用外键,如果要做外键关联可以参考这篇文章
 
2.注释无法更新到数据库
如果一个个注释都手动添加到数据库,几十张表,会不会很蛋疼:
然后看网上给出的思路,根据生成的xml 获取注释,更新到数据库
如果大家有什么工具,希望大家分享下 -,-,
 
下面简单介绍下思路:
 
 
两个项目
1:DbContext项目,就是model-first中对应数据库实体的项目,一般都是单独放在一个项目中
2:控制台程序,您也可以做成web,或者窗体,这边我为了省事做了控制台程序
(不知道为什么,博客园提示无法上传图片,下次补齐图片,先用文字描述。。。)
 
控制台程序添加对DbContext项目的引用,
右击DbContext项目,在生成中的 勾选 输出 “xml 文档文件(X)” bin\Debug\netcoreapp2.1\***.xml ,这个xml文件包含了项目中实体的注释
 
你大概可以看到xml文件中的内容大概是如下
  <member name="T:TmcService.Core.Model.TestTable">
            <summary>
            用于测试
            </summary>
  </member>
   <member name="P:TmcService.Core.Model.TmcSuppliers.SupplierCode">
            <summary>
            主键
            </summary>
   </member>
   <member name="P:TmcService.Core.Model.TmcSuppliers.Name">
            <summary>
            名称
            </summary>
   </member>

可以看到表明 的xml节点   T:TmcService.Core.Model.TestTable

和字段的xml节点     P:TmcService.Core.Model.TmcSuppliers.Name

好了基础工作做完我们就开始下一步

1.读取xml文件,获取每一个节点,将结果集存到list中,
 
2.使用反射获取程序集和表的对应关系存到字典中,
代码如下,数据库操作是用的Dapper,应为数据库mysql所以用了 Pomelo.EntityFrameworkCore.MySql 在nuget都可以直接安装
代码中部分命名空间做了处理
  1 namespace TmcService.GenertageAnnotationToDb
  2 {
  3     class Program
  4     {
  5         private static MySqlConnection con = new MySqlConnection("连接字符串");
  6 
  7         static void Main(string[] args)
  8         {
  9             Console.WriteLine($"如果出现两个命名空间包含相同的字符串的情况下:\n" +
 10                 $"类名:Cofig  命名空间:TmcService.Core.Model \n" +
 11                 $"类名:CofigDetail  命名空间:TmcService.Core.Model \n" +
 12                 $"这种情况下会发生异常,可以手动将拼接的字段生成sql脚本手动更新  \n");
 13             Console.WriteLine("按任意键更新数据库注释...\n");
 14             Console.ReadKey();
 15             try
 16             {
 17                 Console.WriteLine("注释更新中...");
 18                 UpdateAnnonation();
 19                 Console.WriteLine("更新成功按任意键退出...");
 20             }
 21             catch (Exception ex)
 22             {
 23                 Console.WriteLine("更新失败 \n");
 24                 Console.WriteLine(ex.ToString());
 25             }
 26             Console.ReadKey();
 27         }
 28 
 29         /// <summary>
 30         /// 获取数据类名和对应的数据库表名,返回一个dic
 31         /// </summary>
 32         /// <returns></returns>
 33         private static Dictionary<string, string> GetAllCalssMapperDbName()
 34         {
 35             Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();
 36 
 37             //引用model,DbContext的dll
 38             string dllName = AppDomain.CurrentDomain.BaseDirectory + @"***";
 39             Assembly assembly = Assembly.LoadFrom(dllName);
 40 
 41             //获取数据库映射到数据库的实体类(根据情况自行处理)
 42             var typies = assembly.GetTypes().Where(o => o.FullName.Contains("***") && !o.FullName.Contains("***")).ToList();
 43 
 44             //创建对象的实例,获取对象的属性,获取对象在数据库对应的表,
 45             typies.ForEach(o =>
 46             {
 47                 Object obj = Activator.CreateInstance(o);
 48                 var attribute = o.GetCustomAttributes(typeof(TableAttribute), false).FirstOrDefault();
 49                 if (attribute != null)
 50                 {
 51                     keyValuePairs.Add(o.FullName, ((TableAttribute)attribute).Name);
 52                 }
 53             });
 54             return keyValuePairs;
 55         }
 56 
 57         /// <summary>
 58         /// 根据根据dic 匹配类和表关系,将字段标注更新到数据库
 59         /// </summary>
 60         private static List<AnnonationModel> GerAnnonationFromXmlDoc()
 61         {
 62             var keyValuePairs = GetAllCalssMapperDbName();
 63 
 64             XmlDocument xmlDoc = new XmlDocument();
 65             xmlDoc.Load("dbcontext.xml");
 66             var list = xmlDoc.SelectSingleNode("doc").SelectSingleNode("members");
 67             var annonationList = new List<AnnonationModel>();
 68             foreach (var item in list)
 69             {
 70                 AnnonationModel annonationmodel = new AnnonationModel();
 71                 var member = (XmlNode)item;
 72                 var annotation = member.SelectSingleNode("summary");
 73                 string summary = string.Empty;
 74                 var attr = member.Attributes["name"];
 75                 var attrVal = string.Empty;
 76                 if (attr != null)
 77                 {
 78                     attrVal = member.Attributes["name"].Value;
 79                 }
 80                 if (annotation != null)
 81                 {
 82                     summary = (annotation).InnerText;
 83                 }
 84                 annonationmodel.Annonation = summary;
 85                 annonationmodel.ClassName = attrVal;
 86                 annonationList.Add(annonationmodel);
 87             }
 88             return annonationList;
 89         }
 90 
 91         /// <summary>
 92         /// 更新
 93         /// </summary>
 94         private static void UpdateAnnonation()
 95         {
 96             //更新数据库字段注释
 97             var keyValuePairs = GetAllCalssMapperDbName();
 98             var annonationList = GerAnnonationFromXmlDoc();
 99 
100             string sqls = string.Empty;
101 
102             foreach (var item in keyValuePairs)
103             {
104                 var className = item.Key;
105                 var tableName = item.Value;
106 
107                 //获取注释的所有属性
108                 var fields = annonationList.Where(o => o.ClassName.Contains(className)).ToList();
109 
110                 StringBuilder sb = new StringBuilder();
111 
112                 foreach (var o in fields)
113                 {
114                     if (!o.ClassName.Contains("T:"))
115                     {
116                         string[] str = o.ClassName.Split(".");
117                         var len = str.Length;
118                         var attrName = str[len - 1];
119                         //mql数据库关键字处理
120                         if (attrName == "Name" || attrName == "Status")
121                         {
122                             attrName = "`" + attrName + "`";
123                         }
124                         string sql = $" alter table {tableName} modify column {attrName} int comment'{o.Annonation}'; \n";
125                         sb.Append(sql);
126                     }
127                 }
128                 sqls += sb.ToString();
129             }
130             con.Execute(sqls);
131         }
132     }
133 
134     public class AnnonationModel
135     {
136         public string ClassName { get; set; }
137         public string Annonation { get; set; }
138 
139     }
140 }
View Code

 

posted on 2018-09-07 17:25  马利克  阅读(291)  评论(0编辑  收藏  举报

导航