对于EF Core CodeFirst模式下的开发,对Decimal类型的字段需要设置精度,一般我们是通过Fluent API进行设置,代码示例
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<YearPlan>().Property(x=>x.CarSales).HasColumnType("decimal(18,2)");
base.OnModelCreating(modelBuilder);
}
但是,在开发过程中,出现较多的数据表的情况下,在使用Fluent API方式去配置的话,一个会降低开发效率,另外会增加后期的维护工作量,那么我们可以通过自定义字段属性的方式设置精度
创建decimal精度自定义属性 DecimalPrecisionAttribute
using System;
using System.Collections.Generic;
using System.Text;
namespace Cari.Disp.Context
{
/// <summary>
/// 自定义Decimal类型的精度属性
/// </summary>
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
public sealed class DecimalPrecisionAttribute:Attribute
{
private byte precision = 18;
public byte scale = 4;
/// <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;
}
/// <summary>
/// 精确度(默认18)
/// </summary>
public byte Precision
{
get { return precision; }
set { precision = value; }
}
/// <summary>
/// 保留位数(默认4)
/// </summary>
public byte Scale
{
get { return scale; }
set { scale = value; }
}
}
}
在实体类中,为字段添加该属性,代码示例:
/// <summary>
/// 日计划
/// </summary>
public class DayPlan
{
/// <summary>
/// 年月日
/// </summary>
[Required]
[Column(TypeName ="date")]
[Description("日期")]
[MaxLength(50)]
public DateTime PlanDate { get; set; }
/// <summary>
/// 生产日历月份
/// </summary>
[Description("生产日历月份")]
[MaxLength(50)]
public string WorkCalendarMonth { get; set; }
/// <summary>
/// 汽车销售计划
/// </summary>
[DecimalPrecision(18, 2)]
[Description("汽车销售计划")]
public decimal? CarSales { get; set; }
/// <summary>
/// 铁路销售计划
/// </summary>
[DecimalPrecision(18, 2)]
[Description("铁路销售计划")]
public decimal? RailwaySales { get; set; }
/// <summary>
/// 原煤入洗量计划
/// </summary>
[DecimalPrecision(18, 2)]
[Description("原煤入洗量计划")]
public decimal? CoalWashing { get; set; }
/// <summary>
/// 精煤产量计划
/// </summary>
[DecimalPrecision(18, 2)]
[Description("精煤产量计划")]
public decimal? CleanCoalOutput { get; set; }
/// <summary>
/// 掘进煤日计划产量
/// </summary>
[DecimalPrecision(18, 2)]
[Description("掘进煤日计划产量")]
public decimal? JjmPlan { get; set; }
/// <summary>
/// 开拓日计划进尺
/// </summary>
[DecimalPrecision(18, 2)]
[Description("开拓日计划进尺")]
public decimal? KtjcPlan { get; set; }
/// <summary>
/// 回采日计划进尺
/// </summary>
[DecimalPrecision(18, 2)]
[Description("回采日计划进尺")]
public decimal? HcjcPlan { get; set; }
/// <summary>
/// 综采日计划 PS:综采产量计划的总和
/// </summary>
[DecimalPrecision(18, 2)]
[Description("综采日计划")]
public decimal? DayOutputPlan { get; set; }
/// <summary>
/// 日产量计划 PS:综采产量计划的总和+掘进煤日计划产量
/// </summary>
[DecimalPrecision(18, 2)]
[Description("日产量计划")]
public decimal TotalOutput { get; set; }
/// <summary>
/// 日计划进尺 PS:开拓日计划进尺+回采日计划进尺
/// </summary>
[DecimalPrecision(18, 2)]
[Description("日计划进尺")]
public decimal TotalJc { get; set; }
}
然后,在OnModelCreating中,通过DecimalPrecisionAttribute配置精度
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
//modelBuilder.Entity<BaseEntity>().HasQueryFilter(x => !x.Deleted);
//modelBuilder.Conventions.Add(new DecimalPrecisionAttributeConvention());
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
var type = entityType.ClrType;
// 省略其它无关的代码
if (typeof(BaseEntity).IsAssignableFrom(type))
{
entityType.AddSoftDeleteQueryFilter();
//通过自定义decimalAttribute设置decimal精度
var decimalAttributes = type.GetProperties().Where(c => c.IsDefined(typeof(DecimalPrecisionAttribute), true)).ToArray();
foreach (var decimalAttr in decimalAttributes)
{
var precis = decimalAttr.GetCustomAttribute<DecimalPrecisionAttribute>();
modelBuilder.Entity(type).Property(decimalAttr.Name).HasColumnType($"decimal({precis.Precision},{precis.Scale})");
}
}
}
base.OnModelCreating(modelBuilder);
}