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

目標(biāo):
1.實現(xiàn)entity的自動發(fā)現(xiàn)和mapper設(shè)置.
2.默認(rèn)字符串長度,而不是nvarchar(max).
3.decimal設(shè)置精度

實現(xiàn)目標(biāo)1:繼承RelationalModelCustomizer,重寫Customize方法。

當(dāng)然,我們也可以重寫dbcontext的OnModelCreating方法,but,我們怎么能這么low呢。必須要用點高級玩意是吧,當(dāng)然這也是更底層的擴(kuò)展方式。項目里面有多個dbcontext的話,在這里集中擴(kuò)展管理比較方便。
在然后,這個RelationalModelCustomizer繼承自ModelCustomizer。在聯(lián)想到efcore未來的版本會支持redis,nosql什么的。到時候估計還回有一個osqlModelCustomizer之類的吧,期待中......
Android培訓(xùn),安卓培訓(xùn),手機開發(fā)培訓(xùn),移動開發(fā)培訓(xùn),云培訓(xùn)培訓(xùn)

實現(xiàn)目標(biāo)2、3:繼承自CoreConventionSetBuilder類,重寫CreateConventionSet方法。

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

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

//servie,DI注入替換.services.AddSingleton<IModelCustomizer, MyRelationalModelCustomizer>();
services.AddSingleton<ICoreConventionSetBuilder, MyCoreConventionSetBuilder>();//實現(xiàn)entity的自動發(fā)現(xiàn)和mapper設(shè)置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();        //默認(rèn)字符串長度,而不是nvarchar(max).
        //為什么要insert(0,obj),則是因為這個默認(rèn)規(guī)則要最優(yōu)先處理,如果后續(xù)有規(guī)則的話就直接覆蓋了。
        //propertyBuilder.HasMaxLength(32, ConfigurationSource.Convention);
        //理論上我指定了規(guī)則的級別為.Convention,應(yīng)該和順序就沒有關(guān)系了。but,還沒有完成測試,所以我也不知道
        conventionSet.PropertyAddedConventions.Insert(0, new StringDefaultLengthConvention());        //decimal設(shè)置精度
        conventionSet.PropertyAddedConventions.Add(new DecimalPrecisionAttributeConvention());        return conventionSet;
    }
}

下面是StringDefaultLengthConvention和DecimalPrecisionAttributeConvention的實現(xiàn)代碼

//字符串默認(rèn)長度public class StringDefaultLengthConvention : IPropertyAddedConvention
{    public InternalPropertyBuilder Apply(InternalPropertyBuilder propertyBuilder)
    {        if (propertyBuilder.Metadata.ClrType == typeof(string))
            propertyBuilder.HasMaxLength(32, ConfigurationSource.Convention);        return propertyBuilder;
    }
}//attribute方式設(shè)置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類型設(shè)置精度/// </summary>/// <param name="propertyBuilder"></param>/// <param name="precision">精度</param>/// <param name="scale">小數(shù)位數(shù)</param>public static PropertyBuilder<TProperty> HasPrecision<TProperty>(this PropertyBuilder<TProperty> propertyBuilder, int precision = 18, int scale = 4)
{    //fluntapi方式設(shè)置精度  
    ((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;
}

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

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

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

//各種規(guī)則和約定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;
}
//還是各種規(guī)則和約定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 resolved
    conventionSet.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(foreignKeyPropertyDiscoveryConventi

http://www.cnblogs.com/calvinK/p/7234872.html