decimal 精度解决
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
ab68a63bdd
commit
65e47d9918
|
@ -1,10 +1,10 @@
|
|||
namespace System.ComponentModel.DataAnnotations
|
||||
{
|
||||
[AttributeUsage(
|
||||
namespace System.ComponentModel.DataAnnotations;
|
||||
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter,
|
||||
AllowMultiple = false)]
|
||||
public class GuidNotEmptyAttribute : ValidationAttribute
|
||||
{
|
||||
public class GuidNotEmptyAttribute : ValidationAttribute
|
||||
{
|
||||
public const string DefaultErrorMessage = "The {0} field must not be empty";
|
||||
public GuidNotEmptyAttribute() : base(DefaultErrorMessage) { }
|
||||
|
||||
|
@ -24,10 +24,10 @@
|
|||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class NotDefaultAttribute : ValidationAttribute
|
||||
{
|
||||
public class NotDefaultAttribute : ValidationAttribute
|
||||
{
|
||||
public const string DefaultErrorMessage = "The {0} field is is not passed or not set a valid value";
|
||||
public NotDefaultAttribute() : base(DefaultErrorMessage) { }
|
||||
|
||||
|
@ -49,11 +49,11 @@
|
|||
// non-null ref type
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class CanConvertToTimeAttribute : ValidationAttribute
|
||||
{
|
||||
public class CanConvertToTimeAttribute : ValidationAttribute
|
||||
{
|
||||
public const string DefaultErrorMessage = "The {0} field is is not a valid DateTime value";
|
||||
public CanConvertToTimeAttribute() : base(DefaultErrorMessage) { }
|
||||
|
||||
|
@ -73,6 +73,17 @@
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
|
||||
public class DecimalPrecisionAttribute : Attribute
|
||||
{
|
||||
public int Precision { get; }
|
||||
public int Scale { get; }
|
||||
|
||||
public DecimalPrecisionAttribute(int precision, int scale)
|
||||
{
|
||||
Precision = precision;
|
||||
Scale = scale;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,9 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace IRaCIS.Core.Infra.EFCore;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置decimal 默认精度问题 (但是用ef迁移工具的时候,还是会提示No store type was specified for the decimal property,但是迁移文件里面体现了该配置,在dbcontext里写,那么就会没该警告)
|
||||
/// </summary>
|
||||
public class DecimalPrecisionConvention : IModelFinalizingConvention
|
||||
{
|
||||
private readonly int _precision;
|
||||
|
|
|
@ -24,6 +24,7 @@ using System.Reflection.Metadata;
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using Microsoft.VisualBasic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore;
|
||||
|
||||
|
@ -67,7 +68,7 @@ public class IRaCISDBContext : DbContext
|
|||
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
|
||||
{
|
||||
//decimal 不配置,默认精度是18,2
|
||||
configurationBuilder.Conventions.Add(_ => new DecimalPrecisionConvention(18,2));
|
||||
//configurationBuilder.Conventions.Add(_ => new DecimalPrecisionConvention(18,2));
|
||||
//针对字符串使用默认的长度配置为200,如果标注了StringLength 其他长度,就是标注的长度,如果标注了MaxLength 那么就是nvarcharMax
|
||||
configurationBuilder.Conventions.Add(_ => new DefaultStringLengthConvention(200));
|
||||
}
|
||||
|
@ -94,6 +95,35 @@ public class IRaCISDBContext : DbContext
|
|||
#endregion
|
||||
|
||||
|
||||
#region decimal 自定义精度,适配多种数据库
|
||||
//foreach (var entityType in modelBuilder.Model.GetEntityTypes())
|
||||
//{
|
||||
// foreach (var property in entityType.GetProperties())
|
||||
// {
|
||||
// // 如果属性类型是 decimal 或 nullable decimal
|
||||
// if (property.ClrType == typeof(decimal) || property.ClrType == typeof(decimal?))
|
||||
// {
|
||||
// // 获取自定义的 DecimalPrecisionAttribute
|
||||
// var precisionAttr = property.PropertyInfo?.GetCustomAttributes(typeof(DecimalPrecisionAttribute), false)
|
||||
// .FirstOrDefault() as DecimalPrecisionAttribute;
|
||||
|
||||
// if (precisionAttr != null)
|
||||
// {
|
||||
// property.SetPrecision(precisionAttr.Precision);
|
||||
// property.SetScale(precisionAttr.Scale);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // 默认的精度设置
|
||||
// property.SetPrecision(18);
|
||||
// property.SetScale(2);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
#endregion
|
||||
|
||||
//遍历实体模型手动配置
|
||||
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes().Where(q => q.GetInterface(typeof(IEntityTypeConfiguration<>).FullName) != null);
|
||||
foreach (var type in typesToRegister)
|
||||
|
|
|
@ -109,11 +109,41 @@ public partial class <#= EntityType.Name #>: BaseFullAuditEntity
|
|||
<#
|
||||
}
|
||||
}
|
||||
if (property.ClrType == typeof(decimal) || property.ClrType == typeof(decimal?))
|
||||
{
|
||||
var typeName = property.GetColumnType()??""; // 获取数据库类型名称
|
||||
// 匹配 decimal, numeric, 或者 number 格式
|
||||
var match = System.Text.RegularExpressions.Regex.Match(typeName, @"(decimal|numeric|number)\((\d+),(\d+)\)", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
var precision = match.Groups[2].Value;
|
||||
var scale = match.Groups[3].Value;
|
||||
#>
|
||||
[DecimalPrecision(<#= precision #>, <#= scale #>)]
|
||||
<#
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
#>
|
||||
[DecimalPrecision(18, 2)] // 默认值
|
||||
<#
|
||||
}
|
||||
}
|
||||
|
||||
var dataAnnotations = property.GetDataAnnotations(annotationCodeGenerator)
|
||||
.Where(a => !(a.Type == typeof(RequiredAttribute) && Options.UseNullableReferenceTypes && !property.ClrType.IsValueType)
|
||||
&& a.Type != typeof(StringLengthAttribute)); // Åųý StringLengthAttribute
|
||||
&& a.Type != typeof(StringLengthAttribute) // 排除 StringLengthAttribute
|
||||
);
|
||||
|
||||
foreach (var dataAnnotation in dataAnnotations)
|
||||
{
|
||||
//过滤 [Column(TypeName = "decimal(18,1)")] 这种设置TypeName的 直接过滤&& a.Type != typeof(ColumnAttribute) 会报错,很奇怪
|
||||
if(dataAnnotation.Arguments?.Count==0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
#>
|
||||
<#= code.Fragment(dataAnnotation) #>
|
||||
<#
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
4、微软官方针对这些不同的库,生成实体的T4模板是一样的,而且也提供了自定义模板的功能,我们可以在官方模板的基础上进行自定义,以适配属于我们项目的实体生成
|
||||
1)继承我们自己的审计基类
|
||||
2)生成的时候过滤Id 以及我们自己的审计字段
|
||||
3)为适配多种数据库,自定义指定字符串长度(默认长度不用标注,特殊长度才标注)
|
||||
4)为适配多种数据库,自定义精度特性,统一处理
|
||||
|
||||
程序包管理控制台命令行工具使用:
|
||||
|
||||
|
|
Loading…
Reference in New Issue