zoukankan      html  css  js  c++  java
  • 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)” binDebug etcoreapp2.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($"如果出现两个命名空间包含相同的字符串的情况下:
    " +
     10                 $"类名:Cofig  命名空间:TmcService.Core.Model 
    " +
     11                 $"类名:CofigDetail  命名空间:TmcService.Core.Model 
    " +
     12                 $"这种情况下会发生异常,可以手动将拼接的字段生成sql脚本手动更新  
    ");
     13             Console.WriteLine("按任意键更新数据库注释...
    ");
     14             Console.ReadKey();
     15             try
     16             {
     17                 Console.WriteLine("注释更新中...");
     18                 UpdateAnnonation();
     19                 Console.WriteLine("更新成功按任意键退出...");
     20             }
     21             catch (Exception ex)
     22             {
     23                 Console.WriteLine("更新失败 
    ");
     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}'; 
    ";
    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
  • 相关阅读:
    python之定时器Timer
    (转载)Python一篇学会多线程
    docker速记
    IP地址简单入门
    pycharm快捷键及一些常用设置(转载)
    python系列1_travel
    Fluter基础巩固之Dart语言详解<三>
    Fluter基础巩固之Dart语言详解<二>
    Fluter基础巩固之Dart语言详解<一>
    Java精通并发-Condition编程模式详解与分析
  • 原文地址:https://www.cnblogs.com/MarkSun3/p/9606070.html
Copyright © 2011-2022 走看看