【.NET】设置EntityFramework中decimal类型数据精度 [转]

[转]https://blog.csdn.net/u013938578/article/details/78740152

EF中默认的decimal数据精度为两位数,当我们数据库设置的精度大于2时,EF将只会保留到2为精度。

e.g.  2.1999将会被保存为2.20

网上找到常见的方法为重写DbContext的OnModelCreating方法:

  1.  
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
  2.  
    {
  3.  
      modelBuilder.Entity<Product>().Property(x => x.Price).HasPrecision(18, 4);
  4.  
    }

但如果数据表多或者Decimal类型字段多的话,用OnModelCreating的方法将会变得相当冗余,而且不便管理。

我推荐使用Attribute属性标签进行设置,在Entity Model class中decimal的字段上方直接添加自定义拓展的属性标签即可。

e.g.

其中 [DecimalPrecision(18, 4)]即是我们自定义的精度Attribute

具体实现代码如下:

  1.  
    1 /// <summary>
  2.  
    2 /// <para>自定义Decimal类型的精度属性</para>
  3.  
    3 /// </summary>
  4.  
    4 [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
  5.  
    5 public sealed class DecimalPrecisionAttribute : Attribute
  6.  
    6 {
  7.  
    7
  8.  
    8 #region Field
  9.  
    9 private byte _precision = 18;
  10.  
    10 public byte _scale = 4;
  11.  
    11 #endregion
  12.  
    12
  13.  
    13 #region Construct
  14.  
    14 /// <summary>
  15.  
    15 /// <para>自定义Decimal类型的精确度属性</para>
  16.  
    16 /// </summary>
  17.  
    17 /// <param name="precision">precision
  18.  
    18 /// <para>精度(默认18)</para></param>
  19.  
    19 /// <param name="scale">scale
  20.  
    20 /// <para>小数位数(默认4)</para></param>
  21.  
    21 public DecimalPrecisionAttribute(byte precision = 18, byte scale = 4)
  22.  
    22 {
  23.  
    23 Precision = precision;
  24.  
    24 Scale = scale;
  25.  
    25 }
  26.  
    26 #endregion
  27.  
    27
  28.  
    28 #region Property
  29.  
    29 /// <summary>
  30.  
    30 /// 精确度(默认18)
  31.  
    31 /// </summary>
  32.  
    32 public byte Precision
  33.  
    33 {
  34.  
    34 get { return this._precision; }
  35.  
    35 set { this._precision = value; }
  36.  
    36 }
  37.  
    37
  38.  
    38 /// <summary>
  39.  
    39 /// 保留位数(默认4)
  40.  
    40 /// </summary>
  41.  
    41 public byte Scale
  42.  
    42 {
  43.  
    43 get { return this._scale; }
  44.  
    44 set { this._scale = value; }
  45.  
    45 }
  46.  
    46 #endregion
  47.  
    47 }
  48.  
    48
  49.  
    49 /// <summary>
  50.  
    50 /// 用于modelBuilder全局设置自定义精度属性
  51.  
    51 /// </summary>
  52.  
    52 public class DecimalPrecisionAttributeConvention
  53.  
    53 : PrimitivePropertyAttributeConfigurationConvention<DecimalPrecisionAttribute>
  54.  
    54 {
  55.  
    55 public override void Apply(ConventionPrimitivePropertyConfiguration configuration, DecimalPrecisionAttribute attribute)
  56.  
    56 {
  57.  
    57 if (attribute.Precision < 1 || attribute.Precision > 38)
  58.  
    58 {
  59.  
    59 throw new InvalidOperationException("Precision must be between 1 and 38.");
  60.  
    60 }
  61.  
    61 if (attribute.Scale > attribute.Precision)
  62.  
    62 {
  63.  
    63 throw new InvalidOperationException("Scale must be between 0 and the Precision value.");
  64.  
    64 }
  65.  
    65 configuration.HasPrecision(attribute.Precision, attribute.Scale);
  66.  
    66 }
  67.  
    67 }

再在DbContext重写OnModelCreating,添加自定义的DecimalPrecisionAttributeConvention即可以方便地任意添加需要精度控制的字段。

  1.  
    public class Project_DbContext : DbContext
  2.  
    {
  3.  
    public Project_DbContext() : base("DefaultConnection") { }
  4.  
     
  5.  
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
  6.  
    {
  7.  
    modelBuilder.Conventions.Add(new DecimalPrecisionAttributeConvention());
  8.  
    base.OnModelCreating(modelBuilder);
  9.  
    }
  10.  
     
  11.  
    }

 

EF中默认的decimal数据精度为两位数,当我们数据库设置的精度大于2时,EF将只会保留到2为精度。

e.g.  2.1999将会被保存为2.20

网上找到常见的方法为重写DbContext的OnModelCreating方法:

  1.  
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
  2.  
    {
  3.  
      modelBuilder.Entity<Product>().Property(x => x.Price).HasPrecision(18, 4);
  4.  
    }

但如果数据表多或者Decimal类型字段多的话,用OnModelCreating的方法将会变得相当冗余,而且不便管理。

我推荐使用Attribute属性标签进行设置,在Entity Model class中decimal的字段上方直接添加自定义拓展的属性标签即可。

e.g.

其中 [DecimalPrecision(18, 4)]即是我们自定义的精度Attribute

具体实现代码如下:

  1.  
    1 /// <summary>
  2.  
    2 /// <para>自定义Decimal类型的精度属性</para>
  3.  
    3 /// </summary>
  4.  
    4 [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
  5.  
    5 public sealed class DecimalPrecisionAttribute : Attribute
  6.  
    6 {
  7.  
    7
  8.  
    8 #region Field
  9.  
    9 private byte _precision = 18;
  10.  
    10 public byte _scale = 4;
  11.  
    11 #endregion
  12.  
    12
  13.  
    13 #region Construct
  14.  
    14 /// <summary>
  15.  
    15 /// <para>自定义Decimal类型的精确度属性</para>
  16.  
    16 /// </summary>
  17.  
    17 /// <param name="precision">precision
  18.  
    18 /// <para>精度(默认18)</para></param>
  19.  
    19 /// <param name="scale">scale
  20.  
    20 /// <para>小数位数(默认4)</para></param>
  21.  
    21 public DecimalPrecisionAttribute(byte precision = 18, byte scale = 4)
  22.  
    22 {
  23.  
    23 Precision = precision;
  24.  
    24 Scale = scale;
  25.  
    25 }
  26.  
    26 #endregion
  27.  
    27
  28.  
    28 #region Property
  29.  
    29 /// <summary>
  30.  
    30 /// 精确度(默认18)
  31.  
    31 /// </summary>
  32.  
    32 public byte Precision
  33.  
    33 {
  34.  
    34 get { return this._precision; }
  35.  
    35 set { this._precision = value; }
  36.  
    36 }
  37.  
    37
  38.  
    38 /// <summary>
  39.  
    39 /// 保留位数(默认4)
  40.  
    40 /// </summary>
  41.  
    41 public byte Scale
  42.  
    42 {
  43.  
    43 get { return this._scale; }
  44.  
    44 set { this._scale = value; }
  45.  
    45 }
  46.  
    46 #endregion
  47.  
    47 }
  48.  
    48
  49.  
    49 /// <summary>
  50.  
    50 /// 用于modelBuilder全局设置自定义精度属性
  51.  
    51 /// </summary>
  52.  
    52 public class DecimalPrecisionAttributeConvention
  53.  
    53 : PrimitivePropertyAttributeConfigurationConvention<DecimalPrecisionAttribute>
  54.  
    54 {
  55.  
    55 public override void Apply(ConventionPrimitivePropertyConfiguration configuration, DecimalPrecisionAttribute attribute)
  56.  
    56 {
  57.  
    57 if (attribute.Precision < 1 || attribute.Precision > 38)
  58.  
    58 {
  59.  
    59 throw new InvalidOperationException("Precision must be between 1 and 38.");
  60.  
    60 }
  61.  
    61 if (attribute.Scale > attribute.Precision)
  62.  
    62 {
  63.  
    63 throw new InvalidOperationException("Scale must be between 0 and the Precision value.");
  64.  
    64 }
  65.  
    65 configuration.HasPrecision(attribute.Precision, attribute.Scale);
  66.  
    66 }
  67.  
    67 }

再在DbContext重写OnModelCreating,添加自定义的DecimalPrecisionAttributeConvention即可以方便地任意添加需要精度控制的字段。

  1.  
    public class Project_DbContext : DbContext
  2.  
    {
  3.  
    public Project_DbContext() : base("DefaultConnection") { }
  4.  
     
  5.  
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
  6.  
    {
  7.  
    modelBuilder.Conventions.Add(new DecimalPrecisionAttributeConvention());
  8.  
    base.OnModelCreating(modelBuilder);
  9.  
    }
  10.  
     
  11.  
    }

 

原文地址:https://www.cnblogs.com/z45281625/p/14931427.html