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

继承自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<ICoreConventionSetBuilder, MyCoreConventionSetBuilder>();  

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<TAttribute> 他是一个抽象类 其实什么也没有干就是把值取出来了可以看源码

 [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
         /// <summary>
         /// <para>自定义Decimal类型的精确度属性</para>
         /// </summary>
         /// <param name="precision">precision
         /// <para>精度(默认18)</para></param>
         /// <param name="scale">scale
         /// <para>小数位数(默认4)</para></param>
         public DecimalPrecisionAttribute(byte precision = 18, byte scale = 4)
         {
             Precision = precision;
             Scale = scale;
         } 
         #endregion
         
         #region Property
         /// <summary>
         /// 精确度(默认18)
         /// </summary>
         public byte Precision
         {
             get { return this._precision; }
             set { this._precision = value; }
         }
 
         /// <summary>
         /// 保留位数(默认4)
         /// </summary>
         public byte Scale
         {
             get { return this._scale; }
             set { this._scale = value; }
         } 
         #endregion
     }

 


public class DecimalPrecisionAttributeConvention : PropertyAttributeConvention<DecimalPrecisionAttribute>
{
    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<TProperty> HasPrecision<TProperty>(this PropertyBuilder<TProperty> propertyBuilder, int precision = 18, int scale = 4)
{
    //fluntapi方式设置精度    
    ((IInfrastructure<InternalPropertyBuilder>)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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值