MyMigrationsSqlGenerator.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. using Microsoft.EntityFrameworkCore.Metadata;
  2. using Microsoft.EntityFrameworkCore.Migrations.Operations;
  3. using Microsoft.EntityFrameworkCore.Migrations;
  4. using Pomelo.EntityFrameworkCore.MySql.Infrastructure.Internal;
  5. using Pomelo.EntityFrameworkCore.MySql.Migrations;
  6. using System.Collections.Generic;
  7. using System.ComponentModel;
  8. using System.Reflection;
  9. using System;
  10. using System.Linq;
  11. using Microsoft.EntityFrameworkCore.Storage;
  12. using Serilog;
  13. using Microsoft.EntityFrameworkCore.Metadata.Internal;
  14. namespace Business.EntityFrameworkCore
  15. {
  16. /// <summary>
  17. /// 拓展迁移操作:增加数据表和列备注
  18. /// </summary>
  19. public class MyMigrationsSqlGenerator : MySqlMigrationsSqlGenerator
  20. {
  21. public MyMigrationsSqlGenerator(
  22. MigrationsSqlGeneratorDependencies dependencies,
  23. IRelationalAnnotationProvider migrationsAnnotations,
  24. IMySqlOptions mySqlOptions)
  25. : base(dependencies, migrationsAnnotations, mySqlOptions)
  26. {
  27. }
  28. protected override void Generate(MigrationOperation operation, IModel model, MigrationCommandListBuilder builder)
  29. {
  30. base.Generate(operation, model, builder);
  31. Log.Information("AAAA");
  32. if (operation is CreateTableOperation || operation is AlterTableOperation)
  33. CreateTableComment(operation, model, builder);
  34. if (operation is AddColumnOperation || operation is AlterColumnOperation)
  35. CreateColumnComment(operation, model, builder);
  36. }
  37. /// <summary>
  38. /// 创建表注释
  39. /// </summary>
  40. /// <param name="operation"></param>
  41. /// <param name="builder"></param>
  42. private void CreateTableComment(MigrationOperation operation, IModel model, MigrationCommandListBuilder builder)
  43. {
  44. string tableName = string.Empty;
  45. string description = string.Empty;
  46. if (operation is AlterTableOperation)
  47. {
  48. var t = operation as AlterColumnOperation;
  49. tableName = (operation as AlterTableOperation).Name;
  50. }
  51. if (operation is CreateTableOperation)
  52. {
  53. var t = operation as CreateTableOperation;
  54. var addColumnsOperation = t.Columns;
  55. tableName = t.Name;
  56. foreach (var item in addColumnsOperation)
  57. {
  58. CreateColumnComment(item, model, builder);
  59. }
  60. }
  61. description = DbDescriptionHelper.GetDescription(tableName);
  62. Log.Debug($"创建BOM表,返回备注{description}");
  63. if (tableName.IsNullOrWhiteSpace())
  64. throw new Exception("表名为空引起添加表注释异常.");
  65. var sqlHelper = Dependencies.SqlGenerationHelper;
  66. builder
  67. .Append("ALTER TABLE ")
  68. .Append(sqlHelper.DelimitIdentifier(tableName))
  69. .Append(" COMMENT ")
  70. .Append("'")
  71. .Append(description)
  72. .Append("'")
  73. .AppendLine(sqlHelper.StatementTerminator)
  74. .EndCommand();
  75. }
  76. /// <summary>
  77. /// 创建列注释
  78. /// </summary>
  79. /// <param name="operation"></param>
  80. /// <param name="builder"></param>
  81. private void CreateColumnComment(MigrationOperation operation, IModel model, MigrationCommandListBuilder builder)
  82. {
  83. //alter table a1log modify column UUID VARCHAR(26) comment '修改后的字段注释';
  84. string tableName = string.Empty;
  85. string columnName = string.Empty;
  86. string columnType = string.Empty;
  87. string description = string.Empty;
  88. if (operation is AlterColumnOperation)
  89. {
  90. var t = (operation as AlterColumnOperation);
  91. tableName = t.Table;
  92. columnName = t.Name;
  93. var o = new AlterColumnOperation();
  94. o.ClrType = t.ClrType;
  95. o.ColumnType = t.ColumnType;
  96. o.Comment = t.Comment;
  97. o.IsUnicode = t.IsUnicode;
  98. o.MaxLength = t.MaxLength;
  99. o.IsFixedLength = t.IsFixedLength;
  100. o.IsRowVersion = t.IsRowVersion;
  101. columnType = base.GetColumnType(t.Schema, t.Table, t.Name, o, model);
  102. }
  103. if (operation is AddColumnOperation)
  104. {
  105. var t = (operation as AddColumnOperation);
  106. tableName = t.Table;
  107. columnName = t.Name;
  108. var o = new AddColumnOperation();
  109. o.ClrType = t.ClrType;
  110. o.ColumnType = t.ColumnType;
  111. o.Comment = t.Comment;
  112. o.IsUnicode = t.IsUnicode;
  113. o.MaxLength = t.MaxLength;
  114. o.IsFixedLength = t.IsFixedLength;
  115. o.IsRowVersion = t.IsRowVersion;
  116. columnType = GetColumnType(t.Schema, t.Table, t.Name, o, model);
  117. description = DbDescriptionHelper.GetDescription(tableName, columnName);
  118. }
  119. if (columnName.IsNullOrWhiteSpace() || tableName.IsNullOrWhiteSpace() || columnType.IsNullOrWhiteSpace())
  120. throw new Exception("列名为空或表名为空或列类型为空引起添加列注释异常." + columnName + "/" + tableName + "/" + columnType);
  121. var sqlHelper = Dependencies.SqlGenerationHelper;
  122. builder
  123. .Append("ALTER TABLE ")
  124. .Append(sqlHelper.DelimitIdentifier(tableName))
  125. .Append(" MODIFY COLUMN ")
  126. .Append($"`{columnName}`")
  127. .Append(" ")
  128. .Append(columnType)
  129. .Append(" COMMENT ")
  130. .Append("'")
  131. .Append(description)
  132. .Append("'")
  133. .AppendLine(sqlHelper.StatementTerminator)
  134. .EndCommand();
  135. }
  136. }
  137. public class DbDescriptionHelper
  138. {
  139. /// <summary>
  140. /// 命名空间
  141. /// </summary>
  142. public static string _assemblyNamespace { get; set; } = "Bussiness.Model";
  143. public static List<DbDescription> list { get; set; }
  144. /// <summary>
  145. /// 获取表或者字段属性
  146. /// </summary>
  147. /// <param name="table"></param>
  148. /// <param name="column"></param>
  149. /// <returns></returns>
  150. public static string GetDescription(string table, string column = "")
  151. {
  152. Log.Debug($"AAAA:{table}-----{column}");
  153. if (list == null || list.Count== 0)
  154. {
  155. list = GetDescription();
  156. }
  157. if (!string.IsNullOrWhiteSpace(table))
  158. {
  159. if (string.IsNullOrWhiteSpace(column))
  160. {
  161. var x = list.FirstOrDefault(p => p.Name == table);
  162. if (x != null)
  163. return x.Description;
  164. return string.Empty;
  165. }
  166. else
  167. {
  168. var x = list.FirstOrDefault(p => p.Name == table);
  169. if (x != null)
  170. {
  171. var y = x.Column;
  172. if (y != null)
  173. {
  174. var z = y.FirstOrDefault(p => p.Name == column);
  175. if (z != null)
  176. return z.Description;
  177. }
  178. }
  179. return string.Empty;
  180. }
  181. }
  182. else
  183. return string.Empty;
  184. }
  185. /// <summary>
  186. /// 获取程序集所有对象注释
  187. /// </summary>
  188. /// <returns></returns>
  189. private static List<DbDescription> GetDescription()
  190. {
  191. var descriptionList = new List<DbDescription>();
  192. var entityAssembly = Assembly.Load(_assemblyNamespace);
  193. var allType = entityAssembly?.GetTypes();
  194. var allClass = allType?.Where(t => t.IsClass).ToList();
  195. foreach (var h in allClass)
  196. {
  197. //表注释
  198. var tableDescription = new DbDescription();
  199. tableDescription.Column = new List<DbDescription>();
  200. tableDescription.Name = h.Name;
  201. var tobjs = h.GetCustomAttributes(typeof(DescriptionAttribute), true);
  202. tableDescription.Description = GetPropertyDescription(h);
  203. //所有属性注释
  204. PropertyInfo[] peroperties = h.GetProperties();
  205. foreach (PropertyInfo property in peroperties)
  206. {
  207. var column = new DbDescription();
  208. column.Name = property.Name;
  209. column.Description = GetPropertyDescription(property);
  210. tableDescription.Column.Add(column);
  211. }
  212. descriptionList.Add(tableDescription);
  213. }
  214. return descriptionList;
  215. }
  216. /// <summary>
  217. /// 获取属性注释
  218. /// </summary>
  219. /// <returns></returns>
  220. private static string GetPropertyDescription(PropertyInfo property)
  221. {
  222. var objs = property.GetCustomAttributes(typeof(DescriptionAttribute), true);
  223. return CommondDescription(objs);
  224. }
  225. /// <summary>
  226. /// 获取对象注释
  227. /// </summary>
  228. /// <returns></returns>
  229. private static string GetPropertyDescription(Type type)
  230. {
  231. var objs = type.GetCustomAttributes(typeof(DescriptionAttribute), true);
  232. return CommondDescription(objs);
  233. }
  234. private static string CommondDescription(object[] objs)
  235. {
  236. if (objs != null && objs.Length > 0)
  237. {
  238. return ((DescriptionAttribute)objs[0]).Description;
  239. }
  240. return "";
  241. }
  242. }
  243. /// <summary>
  244. /// 表注释信息
  245. /// </summary>
  246. public class DbDescription
  247. {
  248. /// <summary>
  249. /// 名称
  250. /// </summary>
  251. public string Name { get; set; }
  252. /// <summary>
  253. /// 注释
  254. /// </summary>
  255. public string Description { get; set; }
  256. /// <summary>
  257. /// 表字段集合
  258. /// </summary>
  259. public List<DbDescription> Column { get; set; }
  260. }
  261. }