c# ef core 对数据类型decmial的扩展

为什么80%的码农都做不了架构师?>>>   hot3.png

继承自CoreConventionSetBuilder类,重写CreateConventionSet方法。

注意事项:CoreConventionSetBuilder 此api 官方源码说后期可能会移除目前不清楚当前版本2.1.1 ef

 Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal 源代码类库目录CoreConventionSetBuilder 类
//

其目的就是ef core 对decmial 默认保留小数2位(18,2) 导致项目中的精度不够需要重新定义数据类型(18,4) 

源代码中CreateConventionSet方法默然实现了很多初始化的元数据结构对象

实现:MyCoreConventionSetBuilder类继承CoreConventionSetBuilder 类重写CreateConventionSet方法。

 通过Di替换 ICoreConventionSetBuilder 原始的CoreConventionSetBuilder

services.AddSingleton();  

public class MyCoreConventionSetBuilder : CoreConventionSetBuilder  {  

   public MyCoreConventionSetBuilder(CoreConventionSetBuilderDependencies dependencies) : base(dependencies){}  

     public override ConventionSet CreateConventionSet()  

  {  

      var conventionSet = base.CreateConventionSet();  

        //默认字符串长度,而不是nvarchar(max).  

        //为什么要insert(0,obj),则是因为这个默认规则要最优先处理,如果后续有规则的话就直接覆盖了。          //

      propertyBuilder.HasMaxLength(32, ConfigurationSource.Convention);     

       //decimal设置精度     

     conventionSet.PropertyAddedConventions.Add(new DecimalPrecisionAttributeConvention());     

     return conventionSet;    

     }

  }

public class StringDefaultLengthConvention : IPropertyAddedConvention
{
    public InternalPropertyBuilder Apply(InternalPropertyBuilder propertyBuilder)
    {
        if (propertyBuilder.Metadata.ClrType == typeof(string))
            propertyBuilder.HasMaxLength(32, ConfigurationSource.Convention);
        return propertyBuilder;
    }
}
//attribute方式设置decimal精度  

//DecimalPrecisionAttribute 自己简单实现一个可以了继承 Attribute

 

 Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal  都都这个类库中 

源代码有很多对象 PropertyAttributeConvention 属性特性对象

字符串长度特性 StringLengthAttributeConvention 默认系统以实现  StringLengthAttribute

时间对象    TimestampAttributeConvention  默认系统以实现 TimestampAttribute

不可以为空 验证 RequiredPropertyAttributeConvention 默认系统以实现 RequiredAttribute

同理我们就可以构造自己的属性对象

PropertyAttributeConventiont 他是一个抽象类 其实什么也没有干就是把值取出来了可以看源码

 [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
     public sealed class DecimalPrecisionAttribute : Attribute
     {
 
         #region Field
         private byte _precision = 18;
         public byte _scale = 4;
         #endregion
 
         #region Construct
         ///


         /// 自定义Decimal类型的精确度属性
         ///

         /// precision
         /// 精度(默认18)
         /// scale
         /// 小数位数(默认4)
         public DecimalPrecisionAttribute(byte precision = 18, byte scale = 4)
         {
             Precision = precision;
             Scale = scale;
         } 
         #endregion
         
         #region Property
         ///
         /// 精确度(默认18)
         ///

         public byte Precision
         {
             get { return this._precision; }
             set { this._precision = value; }
         }
 
         ///
         /// 保留位数(默认4)
         ///

         public byte Scale
         {
             get { return this._scale; }
             set { this._scale = value; }
         } 
         #endregion
     }

 


public class DecimalPrecisionAttributeConvention : PropertyAttributeConvention
{
    public override InternalPropertyBuilder Apply(InternalPropertyBuilder propertyBuilder, DecimalPrecisionAttribute attribute, MemberInfo clrMember)
    {
        if (propertyBuilder.Metadata.ClrType == typeof(decimal))
            propertyBuilder.HasPrecision(attribute.Precision, attribute.Scale);
        return propertyBuilder;
    }  

}

///实现扩展方法

public static PropertyBuilder HasPrecision(this PropertyBuilder propertyBuilder, int precision = 18, int scale = 4)
{
    //fluntapi方式设置精度    
    ((IInfrastructure)propertyBuilder).Instance.HasPrecision(precision, scale);

    return propertyBuilder;
}

public static InternalPropertyBuilder HasPrecision(this InternalPropertyBuilder propertyBuilder, int precision, int scale)
{

   // 这里的目的就是为了得到这个对象RelationalPropertyBuilderAnnotations调用HasColumnType方法
    propertyBuilder.Relational(ConfigurationSource.Explicit).HasColumnType($"decimal({precision},{scale})");

    return propertyBuilder;
}

转载于:https://my.oschina.net/stuyun/blog/2396105

你可能感兴趣的:(c# ef core 对数据类型decmial的扩展)