EF中默认的decimal数据精度为两位数,当我们数据库设置的精度大于2时,EF将只会保留到2为精度。
e.g. 2.1999将会被保存为2.20
网上找到常见的方法为重写DbContext的OnModelCreating方法:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Product>().Property(x => x.Price).HasPrecision(18, 4); }
但如果数据表多或者Decimal类型字段多的话,用OnModelCreating的方法将会变得相当冗余,而且不便管理。
我推荐使用Attribute属性标签进行设置,在Entity Model class中decimal的字段上方直接添加自定义拓展的属性标签即可。
e.g.
其中 [DecimalPrecision(18, 4)]即是我们自定义的精度Attribute
具体实现代码如下:
1 /// <summary> 2 /// <para>自定义Decimal类型的精度属性</para> 3 /// </summary> 4 [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] 5 public sealed class DecimalPrecisionAttribute : Attribute 6 { 7 8 #region Field 9 private byte _precision = 18; 10 public byte _scale = 4; 11 #endregion 12 13 #region Construct 14 /// <summary> 15 /// <para>自定义Decimal类型的精确度属性</para> 16 /// </summary> 17 /// <param name="precision">precision 18 /// <para>精度(默认18)</para></param> 19 /// <param name="scale">scale 20 /// <para>小数位数(默认4)</para></param> 21 public DecimalPrecisionAttribute(byte precision = 18, byte scale = 4) 22 { 23 Precision = precision; 24 Scale = scale; 25 } 26 #endregion 27 28 #region Property 29 /// <summary> 30 /// 精确度(默认18) 31 /// </summary> 32 public byte Precision 33 { 34 get { return this._precision; } 35 set { this._precision = value; } 36 } 37 38 /// <summary> 39 /// 保留位数(默认4) 40 /// </summary> 41 public byte Scale 42 { 43 get { return this._scale; } 44 set { this._scale = value; } 45 } 46 #endregion 47 } 48 49 /// <summary> 50 /// 用于modelBuilder全局设置自定义精度属性 51 /// </summary> 52 public class DecimalPrecisionAttributeConvention 53 : PrimitivePropertyAttributeConfigurationConvention<DecimalPrecisionAttribute> 54 { 55 public override void Apply(ConventionPrimitivePropertyConfiguration configuration, DecimalPrecisionAttribute attribute) 56 { 57 if (attribute.Precision < 1 || attribute.Precision > 38) 58 { 59 throw new InvalidOperationException("Precision must be between 1 and 38."); 60 } 61 if (attribute.Scale > attribute.Precision) 62 { 63 throw new InvalidOperationException("Scale must be between 0 and the Precision value."); 64 } 65 configuration.HasPrecision(attribute.Precision, attribute.Scale); 66 } 67 }
再在DbContext重写OnModelCreating,添加自定义的DecimalPrecisionAttributeConvention即可以方便地任意添加需要精度控制的字段。
public class Project_DbContext : DbContext { public Project_DbContext() : base("DefaultConnection") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Add(new DecimalPrecisionAttributeConvention()); base.OnModelCreating(modelBuilder); } }