EF Core 通过自定义属性实现Decimal精度配置

本文介绍如何通过自定义DecimalPrecisionAttribute属性,避免在Entity Framework Core中逐个配置Decimal类型字段精度,提高开发效率并简化后期维护。示例展示了如何在实体类中应用该属性,并在OnModelCreating中根据属性设置数据库列的精度。
摘要由CSDN通过智能技术生成

对于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);
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值