实体枚举字段注释反向生成数据库注释sql

原理

通过反射实体所在程序集,得到枚举值列表,再通过sql获取数据库表结构,两者拼接成sql。

规范

实体枚举字段最好也加上Description特性,方便多次更新;

代码

实体定义

public partial class ProviderContract : Entity<int>
{
	/// <summary>
	/// 自增Id
	/// </summary>
	[Column("Id")]
	public override int Id { get; set; }

	/// <summary>
	/// 供应商ID
	/// </summary>
	public int ProviderId { get; set; }

	/// <summary>
	/// 合同编号
	/// </summary>
	public string ContractNo { get; set; }

	/// <summary>
	/// 主营类目
	/// </summary>
	public ContractGoodsType GoodsType { get; set; }

	/// <summary>
	/// 创建时间
	/// </summary>
	public DateTime CreatedTime { get; set; }

	/// <summary>
	/// 修改时间
	/// </summary>
	public DateTime? ModifiedTime { get; set; }
}

枚举定义

当读取不到枚举值的Description特性时,采用字段名称代替;

public enum ContractGoodsType
    {
        None = 0,

        /// <summary>
        /// 酒店
        /// </summary>
        Hotel = 1,

        /// <summary>
        /// 门票
        /// </summary>
        Ticket = 2,

        /// <summary>
        /// 市区娱乐
        /// </summary>
        UrbanEntertainment = 3,

        /// <summary>
        /// 实物
        /// </summary>
        MaterialObject = 7,
    }

测试代码

public void Test()
{
	var exceptTypeNames = new string[] { "AppId", "ApplicationId" };
	var allEnumTypes = Assembly.Load("Core").GetTypes()
		.Where(t => t.Namespace == "Core.Entities")
		.SelectMany(r => r.GetProperties()
			.Where(p => p.PropertyType.IsEnum && !p.CustomAttributes.Any() && !exceptTypeNames.Contains(p.Name)))
		.Select(p => new
		{
			TableName = p.ReflectedType.Name,
			ColumnName = p.Name,
			EnumType = p.PropertyType
		}).OrderBy(r => r.ColumnName).ToList();
	List<TableDeclare> list;
	using (var dapper = new DapperHelper())
	{
		var sql = @"select table_name, column_name, column_comment, column_type, column_default, is_nullable from information_schema.columns
					where table_schema='test'";
		list = dapper.Query<TableDeclare>(sql).ToList();
	}
	foreach (var item in allEnumTypes)
	{
		var enumDtos = item.EnumType.GetFields().Skip(1).Select(e => new
		{
			EnumValue = (int)e.GetValue(null),
			EnumName = e.Name,
			EnumDescAttr = e.GetCustomAttributes()
			.Where(ac => ac.GetType() == typeof(DescriptionAttribute)).FirstOrDefault()
			as DescriptionAttribute,
		}).ToList();
		var remark = string.Join(',',
			enumDtos.Select(e => e.EnumValue + ":" + (e.EnumDescAttr == null ? e.EnumName : e.EnumDescAttr?.Description)));
		var column = list.Where(l => l.table_name == item.TableName.ToLower() && l.column_name == item.ColumnName).FirstOrDefault();
		//过滤原注释包含数字
		if (column != null && !column.column_comment.Any(c => int.TryParse(c.ToString(), out int _)))
		{
			var nullable = column.is_nullable == "YES" ? " null " : string.Empty;
			var defalutValue = column.column_default == null ? string.Empty : " default " + column.column_default + " ";
			Debug.WriteLine($"ALTER TABLE `{column.table_name}` MODIFY COLUMN `{column.column_name}` {column.column_type}{nullable}{defalutValue} COMMENT '{column.column_comment}({remark})';");
		}
	}
}

private class TableDeclare
{
	public string table_name { get; set; }
	public string column_name { get; set; }
	public string column_comment { get; set; }
	public string column_type { get; set; }
	public string column_default { get; set; }
	public string is_nullable { get; set; }
}

生成的sql效果

ALTER TABLE `providercontract` MODIFY COLUMN `GoodsType` int(11) null  default 0  COMMENT '主营类目(0:None,1:Hotel,2:Ticket,3:UrbanEntertainment,7:MaterialObject)'
原文地址:https://www.cnblogs.com/zk-ljc/p/12349002.html