当前位置 博文首页 > 卖代码的小当家:【繁星Code】如何在EF将实体注释写入数据库中

    卖代码的小当家:【繁星Code】如何在EF将实体注释写入数据库中

    作者:卖代码的小当家 时间:2021-02-06 16:22

            最近在项目中需要把各个字段的释义写到数据库中,该项目已经上线很长时间了,数据库中的字段没有上千也有上百个,要是一个项目一个项目打开然后再去找对应字段查看什么意思,估计要到明年过年了。由于项目中使用EntityFramework,本身这个项目只有手动设置字段注释的功能,Coder平时写代码的时候都懒得写注释,更别提能在配置数据库的时候将注释配置进去,所以如何在EF中自动将实体注释写入数据库,减轻Coder的压力(ru he tou lan)尤为重要。gitee地址:https://gitee.com/lbqman/Blog20210206.git 。下面进入正题。

    一、实现思路

            在FluentAPI中提供了HasComment方法,如下
     
     
     
     
     
    11
     
     
     
    1
        /// <summary>Configures a comment to be applied to the column</summary>
    2
        /// <typeparam name="TProperty"> The type of the property being configured. </typeparam>
    3
        /// <param name="propertyBuilder"> The builder for the property being configured. </param>
    4
        /// <param name="comment"> The comment for the column. </param>
    5
        /// <returns> The same builder instance so that multiple calls can be chained. </returns>
    6
        public static PropertyBuilder<TProperty> HasComment<TProperty>(
    7
          [NotNull] this PropertyBuilder<TProperty> propertyBuilder,
    8
          [CanBeNull] string comment)
    9
        {
    10
          return (PropertyBuilder<TProperty>) propertyBuilder.HasComment(comment);
    11
        }
     
     
    也就是说我们要获取到实体对象的注释xml,然后读取对应的字段注释,自动调用改方法即可。需要解决的问题大概有以下几点。
    1. 如何获取当前配置的字段;
    2. 加载Xml,并根据字段获取对应的注释;
    3. 如何将枚举的各项信息都放入注释中;

    二、实现方法

        1.如何获取当前配置的字段

           在获取xml的注释中,需要的信息有实体对应的类型以及对应的字段。而包含这两种类型的方法只有Property这个方法,该方法的出入参如下:
     
     
     
     
     
    2
     
     
     
    1
    public virtual PropertyBuilder<TProperty> Property<TProperty>(
    2
          [NotNull] Expression<Func<TEntity, TProperty>> propertyExpression);
     
     
            所以我们准备对这个方法进行改造。并且根据传入的propertyExpression获取字段名称。方法如下:
     
     
     
     
     
    4
     
     
     
    1
            public static PropertyBuilder<TProperty> SummaryProperty<TEntity, TProperty>(
    2
                this EntityTypeBuilder<TEntity> entityTypeBuilder,
    3
                Expression<Func<TEntity, TProperty>> propertyExpression)
    4
                where TEntity : class
     
     
            根据表达式获取字段名称如下:
     
     
     
     
     
    10
     
     
     
    1
            public static MemberInfo GetMember<T, TProperty>(this Expression<Func<T, TProperty>> expression)
    2
            {
    3
                MemberExpression memberExp;
    4
                if (expression.Body is UnaryExpression unaryExpression)
    5
                    memberExp = unaryExpression.Operand as MemberExpression;
    6
                else
    7
                    memberExp = expression.Body as MemberExpression;
    8
    
    
    9
                return memberExp?.Member;
    10
            }
     
     

      2.加载Xml,并根据字段获取对应的注释

        VS中的Xml格式不在此处过多解释,属性、方法等注释可以根据规律去获取。此处需要注意的是当字段是从父类继承而来并且父类属于不同的dll时,需要获取父类所在dll的xml注释才行,另外枚举也需要同样去处理。虽然获取Xml数据的方法只在更新数据库时才调用,但是还是需要使用字典将数据缓存下来,方便下次快速获取。具体代码如下:
     
     
     
     
     
    204
     
     
     
    1
       /// <summary>
    2
        /// xml注释获取器
    3
        /// </summary>
    4
        internal static class SummaryXmlCacheProvider
    5
        {
    6
            #region TClass
    7
    
    
    8
            /// <summary>
    9
            /// 根据类型初始化该类所在程序集的xml
    10
            /// </summary>
    11
            /// <typeparam name="TClass"></typeparam>
    12
            internal static void InitSummaryXml<TClass>()
    13
            {
    14
                var assembly = Assembly.GetAssembly(typeof(TClass));
    15
                SerializeXmlFromAssembly(assembly);
    16
            }
    17
    
    
    18
            /// <summary>
    19
            /// 根据类型获取该类所在程序集的xml
    20
            /// </summary>
    21
            /// <typeparam name="TClass"></typeparam>
    22
            /// <returns></returns>
    23
            internal static Dictionary<string, string> GetSummaryXml<TClass>()
    24
            {
    25
                var assembly = Assembly.GetAssembly(typeof(TClass));
    26
                return SummaryCache[assembly];
    27
            }
    28
    
    
    29
            /// <summary>
    30
            /// 获取该类在xml的key
    31
            /// </summary>
    32
            /// <typeparam name="TClass"></typeparam>
    33
            /// <returns></returns>
    34
            internal static string GetClassTypeKey<TClass>()
    35
            {
    36
                return TableSummaryRuleProvider.TypeSummaryKey(typeof(TClass).FullName);
    37
            }
    38
    
    
    39
            #endregion
    40
    
    
    41
            #region TProperty
    42
    
    
    43
            /// <summary>
    44
            /// 根据类型以及字段初始化该类所在程序集的xml
    45
            /// </summary>
    46
            /// <typeparam name="TClass"></typeparam>
    47
            /// <typeparam name="TProperty"></typeparam>
    48
            /// <param name="propertyExpression"></param>
    49
            internal static void InitSummaryXml<TClass, TProperty>(Expression<Func<TClass, TProperty>> propertyExpression)
    50
            {
    51
                var propertyAssembly = GetPropertyAssembly(propertyExpression);
    52
                SerializeXmlFromAssembly(propertyAssembly);
    53
            }
    54
    
    
    55
            /// <summary>
    56
            /// 根据类型以及字段获取该类所在程序集的xml
    57
            /// </summary>
    58
            /// <typeparam name="TClass"></typeparam>
    59
            /// <typeparam name="TProperty"></typeparam>
    60
            /// <param name="propertyExpression"></param>
    61
            /// <returns></returns>
    62
            internal static Dictionary<string, string> GetSummaryXml<TClass, TProperty>(
    63
                Expression<Func<TClass, TProperty>> propertyExpression)
    64
            {
    65
                var propertyAssembly = GetPropertyAssembly(propertyExpression);
    66
                return SummaryCache[propertyAssembly];
    
    下一篇:没有了