为什么80%的码农都做不了架构师?>>>
继承自CoreConventionSetBuilder类,重写CreateConventionSet方法。
注意事项:CoreConventionSetBuilder 此api 官方源码说后期可能会移除目前不清楚当前版本2.1.1 ef
Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal 源代码类库目录CoreConventionSetBuilder 类
//
其目的就是ef core 对decmial 默认保留小数2位(18,2) 导致项目中的精度不够需要重新定义数据类型(18,4)
源代码中CreateConventionSet方法默然实现了很多初始化的元数据结构对象
实现:MyCoreConventionSetBuilder类继承CoreConventionSetBuilder 类重写CreateConventionSet方法。
通过Di替换 ICoreConventionSetBuilder 原始的CoreConventionSetBuilder
services.AddSingleton
public class MyCoreConventionSetBuilder : CoreConventionSetBuilder {
public MyCoreConventionSetBuilder(CoreConventionSetBuilderDependencies dependencies) : base(dependencies){}
public override ConventionSet CreateConventionSet()
{
var conventionSet = base.CreateConventionSet();
//默认字符串长度,而不是nvarchar(max).
//为什么要insert(0,obj),则是因为这个默认规则要最优先处理,如果后续有规则的话就直接覆盖了。 //
propertyBuilder.HasMaxLength(32, ConfigurationSource.Convention);
//decimal设置精度
conventionSet.PropertyAddedConventions.Add(new DecimalPrecisionAttributeConvention());
return conventionSet;
}
}
public class StringDefaultLengthConvention : IPropertyAddedConvention
{
public InternalPropertyBuilder Apply(InternalPropertyBuilder propertyBuilder)
{
if (propertyBuilder.Metadata.ClrType == typeof(string))
propertyBuilder.HasMaxLength(32, ConfigurationSource.Convention);
return propertyBuilder;
}
}
//attribute方式设置decimal精度
//DecimalPrecisionAttribute 自己简单实现一个可以了继承 Attribute
Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal 都都这个类库中
源代码有很多对象 PropertyAttributeConvention 属性特性对象
字符串长度特性 StringLengthAttributeConvention 默认系统以实现 StringLengthAttribute
时间对象 TimestampAttributeConvention 默认系统以实现 TimestampAttribute
不可以为空 验证 RequiredPropertyAttributeConvention 默认系统以实现 RequiredAttribute
同理我们就可以构造自己的属性对象
PropertyAttributeConventiont
[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
///
///
///
/// precision
///
/// scale
///
public DecimalPrecisionAttribute(byte precision = 18, byte scale = 4)
{
Precision = precision;
Scale = scale;
}
#endregion
#region Property
///
/// 精确度(默认18)
///
public byte Precision
{
get { return this._precision; }
set { this._precision = value; }
}
///
/// 保留位数(默认4)
///
public byte Scale
{
get { return this._scale; }
set { this._scale = value; }
}
#endregion
}
public class DecimalPrecisionAttributeConvention : PropertyAttributeConvention
{
public override InternalPropertyBuilder Apply(InternalPropertyBuilder propertyBuilder, DecimalPrecisionAttribute attribute, MemberInfo clrMember)
{
if (propertyBuilder.Metadata.ClrType == typeof(decimal))
propertyBuilder.HasPrecision(attribute.Precision, attribute.Scale);
return propertyBuilder;
}
}
///实现扩展方法
public static PropertyBuilder
{
//fluntapi方式设置精度
((IInfrastructure
return propertyBuilder;
}
public static InternalPropertyBuilder HasPrecision(this InternalPropertyBuilder propertyBuilder, int precision, int scale)
{
// 这里的目的就是为了得到这个对象RelationalPropertyBuilderAnnotations调用HasColumnType方法
propertyBuilder.Relational(ConfigurationSource.Explicit).HasColumnType($"decimal({precision},{scale})");
return propertyBuilder;
}