项目背景
先说下项目背景,新接手一个项目,交接文档中不包含数据字典,数据库表结构也没有任何注释,只有项目代码中实体类部分包含部分注释。为了方便后续迭代维护。我需要将实体中对相关字段的注释同步到数据库对应的注释中,但是涉及的表及字段比较多,手工维护比较麻烦,所以考虑通过反射去实现这个功能。
实现逻辑
我把整个功能的实现分了四个步骤:
1.把项目中定义的实体类及注释生成XML文件
2.读取XML文件获取需要同步的实体类信息
3.通过反射往实体类中解析需要的信息
4.拼接需要信息。在数据库中执行
代码实现
第一步
因为项目是创建了一个Model文件夹,所有需要同步的文件都在这个文件夹下,直接从这个文件夹下获取所有cs文件即可。
String path = @"文件路径"; //定义文件夹路径
DirectoryInfo folder = new DirectoryInfo(path); //获取文件夹对象
foreach (FileInfo file in folder.GetFiles("*.cs"))
{
var className = file.Name.Replace(".cs", ""); //获取实体类名
}
第二步
将实体类注释生成到程序集中并输出到XML中进行读取,大家可以参考这个博客
C#读取注释的方法
第三步
通过反射解析需要的信息
System.Reflection.Assembly a = System.Reflection.Assembly.LoadFrom(@"程序集dll文件");
//通过文件名读取文件
System.Type type = a.GetType($"Shdc.Platform.Models.DataModels.{className}");
//获取实体表相关信息
TableAttribute table= (TableAttribute)type.GetCustomAttributes(typeof(TableAttribute), false).First();
//获取定义的表名
var tableName=table.Name;
//获取定义的域名schema
var schema=table.Schema
PropertyInfo[] Propertys = type.GetProperties();
foreach (var item in Propertys)
{
object[] attributes = item.GetCustomAttributes(false);
//通过第二步中的方法获取字段注释
var descName = xmlCommentHelper.GetFieldOrPropertyComment(item);
//列名
var columnName = "";
foreach (var item1 in attributes)
{
ColumnAttribute colum = item1 as ColumnAttribute;
if (colum != null)
{
columnName = colum.Name;
}
}
}
第四步
第三步已经获取到所需的域名、表名、字段名、注释,组装脚本
StringBuilder sb = new StringBuilder();
sb.AppendLine($"comment on column {域名}.{表名}.{列名} is '{注释}';");
//连接数据库执行组装
var reuslt = _dbService.ExecuteSql(sb.ToString()) > 0;