【.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.   }