EF中預設的decimal數據精度為兩位數,當我們資料庫設置的精度大於2時,EF將只會保留到2為精度。 網上找到常見的方法為重寫DbContext的OnModelCreating方法: 但如果數據表多或者Decimal類型欄位多的話,用OnModelCreating的方法將會變得相當冗餘,而且不便管 ...
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); } }