using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Conventions; using System; using System.ComponentModel.DataAnnotations; using System.Linq; namespace IRaCIS.Core.Infra.EFCore; /// /// Efcore 最新支持批量配置字符串类型长度作为保底的 官网参考:https://learn.microsoft.com/zh-cn/ef/core/modeling/bulk-configuration#conventions /// 设置不标注,默认长度,然后标注了与默认长度不一致,那么就是以标注的为准,同时如果标注了MaxLength ,对于mssql 那就是nvarcharMax,对于pgsql 就是text /// public class DefaultStringLengthConvention : IModelFinalizingConvention { private readonly int _defaultLenth; public DefaultStringLengthConvention(int defaultLenth) { _defaultLenth = defaultLenth; } public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext context) { foreach (var property in modelBuilder.Metadata.GetEntityTypes() .SelectMany( entityType => entityType.GetDeclaredProperties() .Where( property => property.ClrType == typeof(string)))) { // 获取 MaxLength 特性 var maxLengthAttribute = property.PropertyInfo?.GetCustomAttributes(typeof(MaxLengthAttribute), false) .FirstOrDefault() as MaxLengthAttribute; // 获取 StringLength 特性 var stringLengthAttribute = property.PropertyInfo?.GetCustomAttributes(typeof(StringLengthAttribute), false) .FirstOrDefault() as StringLengthAttribute; // 输出调试信息,看看是哪种特性生效 if (stringLengthAttribute != null) { //Console.WriteLine($"{property.Name}: StringLength({stringLengthAttribute.MaximumLength})"); property.Builder.HasMaxLength(stringLengthAttribute.MaximumLength); } else if (maxLengthAttribute != null) { //Console.WriteLine($"{property.Name}: MaxLength (no specific length, allowing max)"); } else { //Console.WriteLine($"{property.Name}: Default length 200"); property.Builder.HasMaxLength(_defaultLenth); } } } }