using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace VOL.Entity.MappingConfiguration { public interface IEntityMappingConfiguration { void Map(ModelBuilder b); } public interface IEntityMappingConfiguration : IEntityMappingConfiguration where T : class { void Map(EntityTypeBuilder builder); } public abstract class EntityMappingConfiguration : IEntityMappingConfiguration where T : class { public abstract void Map(EntityTypeBuilder b); public void Map(ModelBuilder b) { Map(b.Entity()); } } public static class ModelBuilderExtenions { private static IEnumerable GetMappingTypes(this Assembly assembly, Type mappingInterface) { return assembly.GetTypes().Where(x => !x.IsAbstract && x.GetInterfaces().Any(y => y.GetTypeInfo().IsGenericType && y.GetGenericTypeDefinition() == mappingInterface)); } public static void AddEntityConfigurationsFromAssembly(this ModelBuilder modelBuilder, Assembly assembly) { var mappingTypes = assembly.GetMappingTypes(typeof(IEntityMappingConfiguration<>)); foreach (var config in mappingTypes.Select(Activator.CreateInstance).Cast()) { config.Map(modelBuilder); } } } } //字符串默认长度 //public class StringDefaultLengthConvention : IPropertyAddedConvention //{ // public InternalPropertyBuilder Apply(InternalPropertyBuilder propertyBuilder) // { // if (propertyBuilder.Metadata.ClrType == typeof(string)) // propertyBuilder.HasMaxLength(32, ConfigurationSource.Convention); // return propertyBuilder; // } //} ////attribute方式设置decimal精度 //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; // } // /// // /// decimal类型设置精度 // /// // /// // /// 精度 // /// 小数位数 // public static PropertyBuilder HasPrecision(this PropertyBuilder propertyBuilder, int precision = 18, int scale = 4) // { // //fluntapi方式设置精度 // ((IInfrastructure)propertyBuilder).Instance.HasPrecision(precision, scale); // return propertyBuilder; // } // public static InternalPropertyBuilder HasPrecision(this InternalPropertyBuilder propertyBuilder, int precision, int scale) // { // propertyBuilder.Relational(ConfigurationSource.Explicit).HasColumnType($"decimal({precision},{scale})"); // return propertyBuilder; // } ////servie,DI注入替换. //services.AddSingleton(); //services.AddSingleton(); ////实现entity的自动发现和mapper设置 //public class MyRelationalModelCustomizer : RelationalModelCustomizer //{ // public MyRelationalModelCustomizer(ModelCustomizerDependencies dependencies) // : base(dependencies) { } // public override void Customize(ModelBuilder modelBuilder, DbContext dbContext) // { // base.Customize(modelBuilder, dbContext); // var sp = (IInfrastructure)dbContext; // var dbOptions = sp.Instance.GetServices(); // foreach (var item in dbOptions) // { // if (item.ContextType == dbContext.GetType()) // ConfigureDbContextEntityService.Configure(modelBuilder, item, dbContext); // } // } //} //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); // //理论上我指定了规则的级别为.Convention,应该和顺序就没有关系了。but,还没有完成测试,所以我也不知道 // conventionSet.PropertyAddedConventions.Insert(0, new StringDefaultLengthConvention()); // //decimal设置精度 // conventionSet.PropertyAddedConventions.Add(new DecimalPrecisionAttributeConvention()); // return conventionSet; // } //}