日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

扩展entity framework core实现默认字符串长度,decimal精度,entity自动注册和配置

發布時間:2023/12/4 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 扩展entity framework core实现默认字符串长度,decimal精度,entity自动注册和配置 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章以efcore 2.0.0-preview2.測試驗證通過。其他版本不保證使用,但是思路不會差太遠。源代碼,報道越短,事情越嚴重!文章越短,內容越精悍!

目標:
1.實現entity的自動發現和mapper設置.
2.默認字符串長度,而不是nvarchar(max).
3.decimal設置精度

實現目標1:繼承RelationalModelCustomizer,重寫Customize方法。

當然,我們也可以重寫dbcontext的OnModelCreating方法,but,我們怎么能這么low呢。必須要用點高級玩意是吧,當然這也是更底層的擴展方式。項目里面有多個dbcontext的話,在這里集中擴展管理比較方便。
在然后,這個RelationalModelCustomizer繼承自ModelCustomizer。在聯想到efcore未來的版本會支持redis,nosql什么的。到時候估計還回有一個osqlModelCustomizer之類的吧,期待中......

實現目標2、3:繼承自CoreConventionSetBuilder類,重寫CreateConventionSet方法。

重寫CreateConventionSet方法,能拿到關鍵的ConventionSet對象。這個對象囊括了諸多的約定配置等等。比如maxlengthattribute屬性標記,stringlength屬性標記,timestamp屬性標記,表id的自動發現規則等等等。。。
那,我們增加2個小小的約定:字符串默認長度(StringDefaultLengthConvention),和decimal精度設置attribute(DecimalPrecisionAttributeConvention)及fluntapi方式.

文章的最后附efcore 所有的可替換擴展service。

//servie,DI注入替換.services.AddSingleton<IModelCustomizer, MyRelationalModelCustomizer>(); services.AddSingleton<ICoreConventionSetBuilder, MyCoreConventionSetBuilder>();
//實現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<IServiceProvider>)dbContext; ? ?
? ? ? ?? ?var dbOptions = sp.Instance.GetServices<DbContextOptions>(); ? ? ? ?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;} }

下面是StringDefaultLengthConvention和DecimalPrecisionAttributeConvention的實現代碼

//字符串默認長度
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<DecimalPrecisionAttribute> { ?
?public override InternalPropertyBuilder Apply(InternalPropertyBuilder propertyBuilder, DecimalPrecisionAttribute attribute, MemberInfo clrMember) ? ?{ ? ? ?
??if (propertyBuilder.Metadata.ClrType == typeof(decimal))propertyBuilder.HasPrecision(attribute.Precision, attribute.Scale); ? ? ?
?? ?return propertyBuilder;}
?? ?/// <summary>
/// decimal類型設置精度
/// </summary>
/// <param name="propertyBuilder"></param>/// <param name="precision">精度</param>/// <param name="scale">小數位數</param>public static PropertyBuilder<TProperty> HasPrecision<TProperty>(this PropertyBuilder<TProperty> propertyBuilder, int precision = 18, int scale = 4) { ? ?//fluntapi方式設置精度 ?((IInfrastructure<InternalPropertyBuilder>)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; }

以上就是實現的代碼,就這么幾行。嗯,還是挺簡單的.

--------------

以下,則是efcore的源代碼。展示了如此之多的可擴展。隨著DI的運用和微軟的開放,嗯。用爛啦,用炸拉(^_^)

//各種規則和約定
public virtual ConventionSet AddConventions(ConventionSet conventionSet){ValueGeneratorConvention valueGeneratorConvention = new RelationalValueGeneratorConvention();ReplaceConvention(conventionSet.BaseEntityTypeChangedConventions, valueGeneratorConvention);ReplaceConvention(conventionSet.PrimaryKeyChangedConventions, valueGeneratorConvention);ReplaceConvention(conventionSet.ForeignKeyAddedConventions, valueGeneratorConvention);ReplaceConvention(conventionSet.ForeignKeyRemovedConventions, valueGeneratorConvention); ?
?var relationalColumnAttributeConvention = new RelationalColumnAttributeConvention();conventionSet.PropertyAddedConventions.Add(relationalColumnAttributeConvention); ?
??var sharedTableConvention = new SharedTableConvention();conventionSet.EntityTypeAddedConventions.Add(new RelationalTableAttributeConvention());conventionSet.EntityTypeAddedConventions.Add(sharedTableConvention);conventionSet.BaseEntityTypeChangedConventions.Add(new DiscriminatorConvention());conventionSet.BaseEntityTypeChangedConventions.Add( ? ?
??? ?new TableNameFromDbSetConvention(Dependencies.Context?.Context, Dependencies.SetFinder));conventionSet.EntityTypeAnnotationChangedConventions.Add(sharedTableConvention);conventionSet.PropertyFieldChangedConventions.Add(relationalColumnAttributeConvention);conventionSet.PropertyAnnotationChangedConventions.Add((RelationalValueGeneratorConvention)valueGeneratorConvention);conventionSet.ForeignKeyUniquenessChangedConventions.Add(sharedTableConvention);conventionSet.ForeignKeyOwnershipChangedConventions.Add(sharedTableConvention);conventionSet.ModelBuiltConventions.Add(new RelationalTypeMappingConvention(Dependencies.TypeMapper));conventionSet.ModelBuiltConventions.Add(sharedTableConvention);conventionSet.ModelAnnotationChangedConventions.Add(new RelationalDbFunctionConvention()); ?
??? ??return conventionSet; } //還是各種規則和約定public virtual ConventionSet CreateConventionSet(){ ?
?var conventionSet = new ConventionSet(); ?
? ?var propertyDiscoveryConvention = new PropertyDiscoveryConvention(Dependencies.TypeMapper); ?
? ? ?var keyDiscoveryConvention = new KeyDiscoveryConvention(); ?
? ? ??var inversePropertyAttributeConvention = new InversePropertyAttributeConvention(Dependencies.TypeMapper);
? ? ??? ?var relationshipDiscoveryConvention = new RelationshipDiscoveryConvention(Dependencies.TypeMapper);conventionSet.EntityTypeAddedConventions.Add(new NotMappedEntityTypeAttributeConvention());conventionSet.EntityTypeAddedConventions.Add(new NotMappedMemberAttributeConvention());conventionSet.EntityTypeAddedConventions.Add(new BaseTypeDiscoveryConvention());conventionSet.EntityTypeAddedConventions.Add(propertyDiscoveryConvention);conventionSet.EntityTypeAddedConventions.Add(keyDiscoveryConvention);conventionSet.EntityTypeAddedConventions.Add(inversePropertyAttributeConvention);conventionSet.EntityTypeAddedConventions.Add(relationshipDiscoveryConvention);conventionSet.EntityTypeAddedConventions.Add(new DerivedTypeDiscoveryConvention());conventionSet.EntityTypeIgnoredConventions.Add(inversePropertyAttributeConvention); ?
? ? ??? ??var foreignKeyIndexConvention = new ForeignKeyIndexConvention(); ? ?var valueGeneratorConvention = new ValueGeneratorConvention();conventionSet.BaseEntityTypeChangedConventions.Add(propertyDiscoveryConvention);conventionSet.BaseEntityTypeChangedConventions.Add(keyDiscoveryConvention);conventionSet.BaseEntityTypeChangedConventions.Add(inversePropertyAttributeConvention);conventionSet.BaseEntityTypeChangedConventions.Add(relationshipDiscoveryConvention);conventionSet.BaseEntityTypeChangedConventions.Add(foreignKeyIndexConvention);conventionSet.BaseEntityTypeChangedConventions.Add(valueGeneratorConvention ); ? ?// An ambiguity might have been resolvedconventionSet.EntityTypeMemberIgnoredConventions.Add(inversePropertyAttributeConvention);conventionSet.EntityTypeMemberIgnoredConventions.Add(relationshipDiscoveryConvention); ?
? ? ??? ???var keyAttributeConvention = new KeyAttributeConvention(); ?
? ? ??? ????var foreignKeyPropertyDiscoveryConvention = new ForeignKeyPropertyDiscoveryConvention(); ?
? ? ??? ???? ?var backingFieldConvention = new BackingFieldConvention(); ? ?var concurrencyCheckAttributeConvention = new ConcurrencyCheckAttributeConvention(); ? ?
? ? ??? ???? ?var databaseGeneratedAttributeConvention = new DatabaseGeneratedAttributeConvention(); ? ?
? ? ??? ???? ?var requiredPropertyAttributeConvention = new RequiredPropertyAttributeConvention(); ?
? ? ??? ???? ? ?var maxLengthAttributeConvention = new MaxLengthAttributeConvention(); ? ?
? ? ??? ???? ? ?var stringLengthAttributeConvention = new StringLengthAttributeConvention(); ?
? ? ??? ???? ? ??var timestampAttributeConvention = new TimestampAttributeConvention();conventionSet.PropertyAddedConventions.Add(backingFieldConvention);conventionSet.PropertyAddedConventions.Add(concurrencyCheckAttributeConvention);conventionSet.PropertyAddedConventions.Add(databaseGeneratedAttributeConvention);conventionSet.PropertyAddedConventions.Add(requiredPropertyAttributeConvention);conventionSet.PropertyAddedConventions.Add(maxLengthAttributeConvention);conventionSet.PropertyAddedConventions.Add(stringLengthAttributeConvention);conventionSet.PropertyAddedConventions.Add(timestampAttributeConvention);conventionSet.PropertyAddedConventions.Add(keyDiscoveryConvention);conventionSet.PropertyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);conventionSet.PropertyAddedConventions.Add(keyAttributeConvention);conventionSet.PrimaryKeyChangedConventions.Add(valueGeneratorConvention);conventionSet.KeyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);conventionSet.KeyAddedConventions.Add(foreignKeyIndexConvention);conventionSet.KeyRemovedConventions.Add(foreignKeyPropertyDiscoveryConvention);conventionSet.KeyRemovedConventions.Add(foreignKeyIndexConvention);conventionSet.KeyRemovedConventions.Add(keyDiscoveryConvention); ?
? ? ??? ???? ? ?? ?var cascadeDeleteConvention = new CascadeDeleteConvention();conventionSet.ForeignKeyAddedConventions.Add(new ForeignKeyAttributeConvention(Dependencies.TypeMapper));conventionSet.ForeignKeyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);conventionSet.ForeignKeyAddedConventions.Add(keyDiscoveryConvention);conventionSet.ForeignKeyAddedConventions.Add(valueGeneratorConvention );conventionSet.ForeignKeyAddedConventions.Add(cascadeDeleteConvention);conventionSet.ForeignKeyAddedConventions.Add(foreignKeyIndexConvention);conventionSet.ForeignKeyRemovedConventions.Add(keyDiscoveryConvention);conventionSet.ForeignKeyRemovedConventions.Add(valueGeneratorConvention );conventionSet.ForeignKeyRemovedConventions.Add(foreignKeyIndexConvention);conventionSet.ForeignKeyUniquenessChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);conventionSet.ForeignKeyUniquenessChangedConventions.Add(foreignKeyIndexConvention);conventionSet.ForeignKeyOwnershipChangedConventions.Add(new NavigationEagerLoadingConvention());conventionSet.ModelBuiltConventions.Add(new ModelCleanupConvention());conventionSet.ModelBuiltConventions.Add(keyAttributeConvention);conventionSet.ModelBuiltConventions.Add(new IgnoredMembersValidationConvention());conventionSet.ModelBuiltConventions.Add(new PropertyMappingValidationConvention(Dependencies.TypeMapper));conventionSet.ModelBuiltConventions.Add(new RelationshipValidationConvention());conventionSet.ModelBuiltConventions.Add(foreignKeyPropertyDiscoveryConvention);conventionSet.NavigationAddedConventions.Add(backingFieldConvention);conventionSet.NavigationAddedConventions.Add(new RequiredNavigationAttributeConvention());conventionSet.NavigationAddedConventions.Add(inversePropertyAttributeConvention);conventionSet.NavigationAddedConventions.Add(foreignKeyPropertyDiscoveryConvention);conventionSet.NavigationAddedConventions.Add(relationshipDiscoveryConvention);conventionSet.NavigationRemovedConventions.Add(relationshipDiscoveryConvention);conventionSet.IndexAddedConventions.Add(foreignKeyIndexConvention);conventionSet.IndexRemovedConventions.Add(foreignKeyIndexConvention);conventionSet.IndexUniquenessChangedConventions.Add(foreignKeyIndexConvention);conventionSet.PropertyNullabilityChangedConventions.Add(cascadeDeleteConvention);conventionSet.PrincipalEndChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);conventionSet.PropertyFieldChangedConventions.Add(keyDiscoveryConvention);conventionSet.PropertyFieldChangedConventions.Add(foreignKeyPropertyDiscoveryConvention);conventionSet.PropertyFieldChangedConventions.Add(keyAttributeConvention);conventionSet.PropertyFieldChangedConventions.Add(concurrencyCheckAttributeConvention);conventionSet.PropertyFieldChangedConventions.Add(databaseGeneratedAttributeConvention);conventionSet.PropertyFieldChangedConventions.Add(requiredPropertyAttributeConvention);conventionSet.PropertyFieldChangedConventions.Add(maxLengthAttributeConvention);conventionSet.PropertyFieldChangedConventions.Add(stringLengthAttributeConvention);conventionSet.PropertyFieldChangedConventions.Add(timestampAttributeConvention); ? ?return conventionSet; }

我就是所有的可替換service啦。不要眼花有點多!,找著合適的用起來!

serviceCollection.AsQueryable().Where(p => p.ServiceType.ToString().StartsWith("Microsoft.EntityFrameworkCore")).Each(sd => {Console.WriteLine($"{sd.Lifetime.ToString().PadRight(15, ' ')}{sd.ServiceType.FullName}"); });

原文地址:http://www.cnblogs.com/calvinK/p/7234872.html


.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

總結

以上是生活随笔為你收集整理的扩展entity framework core实现默认字符串长度,decimal精度,entity自动注册和配置的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。