EF中对decimal类型在实体属性中的精度控制
EF中对decimal类型数据进行存储时,对多位小数默认会截断取2位保存,但一些高精度场合不能满足要求,则需要我们对其改造一下:
1、新建DecimalPrecisionAttribute.cs,最好和上下文在同一个命名空间内,以减少引用
```csharp
using System;
using System.Collections.Generic;
using System.Data.Entity.ModelConfiguration.Configuration;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Web;
namespace AppBoxMvc.Models
{
/// <summary>
/// 精度属性控制
/// </summary>
[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
}
/// <summary>
/// 用于modelBuilder全局设置自定义精度属性
/// </summary>
public class DecimalPrecisionAttributeConvention
: PrimitivePropertyAttributeConfigurationConvention<DecimalPrecisionAttribute>
{
public override void Apply(ConventionPrimitivePropertyConfiguration configuration, DecimalPrecisionAttribute attribute)
{
if (attribute.Precision < 1 || attribute.Precision > 38)
{
throw new InvalidOperationException("Precision must be between 1 and 38.");
}
if (attribute.Scale > attribute.Precision)
{
throw new InvalidOperationException("Scale must be between 0 and the Precision value.");
}
configuration.HasPrecision(attribute.Precision, attribute.Scale);
}
}
}
2、OnModelCreating新增属性
```csharp
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();//移除复数表名的契约
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();//防止黑幕交易 要不然每次都要访问
modelBuilder.HasDefaultSchema("SCM");
//base.OnModelCreating(modelBuilder);
//注册函数
modelBuilder.Conventions.Add(new FunctionsConvention("SCM", this.GetType()));
modelBuilder.Conventions.Add(new DecimalPrecisionAttributeConvention());
}
注意,在NFineFramework架构中数据库方法中可能调用某个上下文,如JobAppDbContext : DbContext,则只需要在该文属性中增加一个注册即可:
modelBuilder.Conventions.Add(new DecimalPrecisionAttributeConvention());//注册Decimal精度函数
```csharp
public class JobAppDbContext : DbContext
{
public JobAppDbContext()
: base("JobAppDbContext")
{
this.Configuration.AutoDetectChangesEnabled = false;
this.Configuration.ValidateOnSaveEnabled = false;
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.ProxyCreationEnabled = false;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
string assembleFileName = Assembly.GetExecutingAssembly().CodeBase.Replace("JobApp.Data.DLL", "JobApp.Mapping.DLL").Replace("file:///", "");
Assembly asm = Assembly.LoadFile(assembleFileName);
var typesToRegister = asm.GetTypes()
.Where(type => !String.IsNullOrEmpty(type.Namespace))
.Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (var type in typesToRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance);
modelBuilder.Conventions.Add(new DecimalPrecisionAttributeConvention());//注册Decimal精度函数
}
base.OnModelCreating(modelBuilder);
}
}
3、实体属性绑定
```csharp
.....
[DecimalPrecision(19, 4)]
public decimal T_SCM_QUTV_BASIC_PRICE { get; set; }//购买价格
[Display(Name = "税后价格")]
[DecimalPrecision(19, 4)]
public decimal T_SCM_QUTV_END_PRICE { get; set; }//税后价格
........
参考博文:https://www.cnblogs.com/su1643/p/10982197.html

在使用EF处理decimal类型时,默认会截断为2位小数,对于需要高精度的场景,需自定义改造。创建DecimalPrecisionAttribute类并加入到数据库上下文的模型构建器中,以实现自定义精度控制。
1679

被折叠的 条评论
为什么被折叠?



