扩展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之类的吧,期待中......
img_58849be3f709238f999abdbdb30a8463.png

实现目标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 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(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}");
});

//output 
//Singleton Microsoft.EntityFrameworkCore.Storage.IDatabaseProvider
//Singleton Microsoft.EntityFrameworkCore.ValueGeneration.IValueGeneratorCache
//Singleton      Microsoft.EntityFrameworkCore.Storage.IRelationalTypeMapper
//Singleton      Microsoft.EntityFrameworkCore.Storage.ISqlGenerationHelper
//Singleton      Microsoft.EntityFrameworkCore.Migrations.IMigrationsAnnotationProvider
//Singleton      Microsoft.EntityFrameworkCore.Storage.IRelationalValueBufferFactoryFactory
//Singleton      Microsoft.EntityFrameworkCore.Infrastructure.IModelValidator
//Scoped         Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.IConventionSetBuilder
//Singleton      Microsoft.EntityFrameworkCore.Update.IUpdateSqlGenerator
//Scoped         Microsoft.EntityFrameworkCore.Update.IModificationCommandBatchFactory
//Scoped         Microsoft.EntityFrameworkCore.ValueGeneration.IValueGeneratorSelector
//Scoped         Microsoft.EntityFrameworkCore.Storage.IRelationalConnection
//Singleton      Microsoft.EntityFrameworkCore.Migrations.IMigrationsSqlGenerator
//Scoped         Microsoft.EntityFrameworkCore.Storage.IRelationalDatabaseCreator
//Scoped         Microsoft.EntityFrameworkCore.Migrations.IHistoryRepository
//Scoped         Microsoft.EntityFrameworkCore.Query.ICompiledQueryCacheKeyGenerator
//Scoped         Microsoft.EntityFrameworkCore.Storage.IExecutionStrategyFactory
//Scoped         Microsoft.EntityFrameworkCore.Query.IQueryCompilationContextFactory
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionTranslators.IMemberTranslator
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionTranslators.ICompositeMethodCallTranslator
//Singleton      Microsoft.EntityFrameworkCore.Query.Sql.IQuerySqlGeneratorFactory
//Singleton      Microsoft.EntityFrameworkCore.Infrastructure.ISingletonOptions
//Singleton      Microsoft.EntityFrameworkCore.ValueGeneration.Internal.ISqlServerValueGeneratorCache
//Singleton      Microsoft.EntityFrameworkCore.Infrastructure.Internal.ISqlServerOptions
//Scoped         Microsoft.EntityFrameworkCore.Update.Internal.ISqlServerUpdateSqlGenerator
//Scoped         Microsoft.EntityFrameworkCore.ValueGeneration.Internal.ISqlServerSequenceValueGeneratorFactory
//Scoped         Microsoft.EntityFrameworkCore.Storage.Internal.ISqlServerConnection
//Singleton      Microsoft.EntityFrameworkCore.Storage.IParameterNameGeneratorFactory
//Singleton      Microsoft.EntityFrameworkCore.Migrations.IMigrationsIdGenerator
//Singleton      Microsoft.EntityFrameworkCore.Update.Internal.IKeyValueIndexFactorySource
//Singleton      Microsoft.EntityFrameworkCore.Infrastructure.IModelSource
//Singleton      Microsoft.EntityFrameworkCore.Infrastructure.IModelCustomizer
//Scoped         Microsoft.EntityFrameworkCore.Migrations.IMigrator
//Singleton      Microsoft.EntityFrameworkCore.Migrations.IMigrationCommandExecutor
//Scoped         Microsoft.EntityFrameworkCore.Migrations.IMigrationsAssembly
//Scoped         Microsoft.EntityFrameworkCore.Storage.IDatabase
//Scoped         Microsoft.EntityFrameworkCore.Update.IBatchExecutor
//Singleton      Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory
//Singleton      Microsoft.EntityFrameworkCore.Storage.IRawSqlCommandBuilder
//Scoped         Microsoft.EntityFrameworkCore.Update.ICommandBatchPreparer
//Singleton      Microsoft.EntityFrameworkCore.Migrations.IMigrationsModelDiffer
//Singleton      Microsoft.EntityFrameworkCore.Storage.ITypeMapper
//Scoped         Microsoft.EntityFrameworkCore.Storage.IDatabaseCreator
//Scoped         Microsoft.EntityFrameworkCore.Storage.IDbContextTransactionManager
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.IMaterializerFactory
//Singleton      Microsoft.EntityFrameworkCore.Query.Internal.IShaperCommandContextFactory
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.IConditionalRemovingExpressionVisitorFactory
//Scoped         Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ICompositePredicateExpressionVisitorFactory
//Singleton      Microsoft.EntityFrameworkCore.Query.Expressions.ISelectExpressionFactory
//Scoped         Microsoft.EntityFrameworkCore.Query.Internal.IExpressionPrinter
//Scoped         Microsoft.EntityFrameworkCore.Query.IRelationalResultOperatorHandler
//Scoped         Microsoft.EntityFrameworkCore.Query.IQueryContextFactory
//Scoped         Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.IEntityQueryableExpressionVisitorFactory
//Scoped         Microsoft.EntityFrameworkCore.Query.IEntityQueryModelVisitorFactory
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.IProjectionExpressionVisitorFactory
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionTranslators.IExpressionFragmentTranslator
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.ISqlTranslatingExpressionVisitorFactory
//Scoped         Microsoft.EntityFrameworkCore.Storage.Internal.INamedConnectionStringResolver
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionTranslators.RelationalCompositeMemberTranslatorDependencies
//Singleton      Microsoft.EntityFrameworkCore.Storage.RelationalSqlGenerationHelperDependencies
//Singleton      Microsoft.EntityFrameworkCore.Storage.RelationalTypeMapperDependencies
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionTranslators.RelationalCompositeExpressionFragmentTranslatorDependencies
//Singleton      Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidatorDependencies
//Singleton      Microsoft.EntityFrameworkCore.Update.UpdateSqlGeneratorDependencies
//Singleton      Microsoft.EntityFrameworkCore.Query.Sql.QuerySqlGeneratorDependencies
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionTranslators.RelationalCompositeMethodCallTranslatorDependencies
//Singleton      Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGeneratorDependencies
//Singleton      Microsoft.EntityFrameworkCore.Migrations.MigrationsAnnotationProviderDependencies
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.SqlTranslatingExpressionVisitorDependencies
//Singleton      Microsoft.EntityFrameworkCore.Storage.ParameterNameGeneratorDependencies
//Singleton      Microsoft.EntityFrameworkCore.Query.Expressions.SelectExpressionDependencies
//Singleton      Microsoft.EntityFrameworkCore.Storage.RelationalValueBufferFactoryDependencies
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.RelationalProjectionExpressionVisitorDependencies
//Scoped         Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.RelationalConventionSetBuilderDependencies
//Scoped         Microsoft.EntityFrameworkCore.Storage.RelationalDatabaseCreatorDependencies
//Scoped         Microsoft.EntityFrameworkCore.Migrations.HistoryRepositoryDependencies
//Scoped         Microsoft.EntityFrameworkCore.Query.RelationalCompiledQueryCacheKeyGeneratorDependencies
//Scoped         Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitorDependencies
//Scoped         Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.RelationalEntityQueryableExpressionVisitorDependencies
//Scoped         Microsoft.EntityFrameworkCore.Storage.RelationalConnectionDependencies
//Scoped         Microsoft.EntityFrameworkCore.Storage.RelationalDatabaseDependencies
//Scoped         Microsoft.EntityFrameworkCore.Query.RelationalQueryCompilationContextDependencies
//Singleton      Microsoft.EntityFrameworkCore.Internal.IDbSetFinder
//Singleton      Microsoft.EntityFrameworkCore.Internal.IDbSetInitializer
//Singleton      Microsoft.EntityFrameworkCore.Internal.IDbSetSource
//Singleton      Microsoft.EntityFrameworkCore.Internal.IEntityFinderSource
//Singleton      Microsoft.EntityFrameworkCore.Metadata.Internal.IEntityMaterializerSource
//Singleton      Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ICoreConventionSetBuilder
//Singleton      Microsoft.EntityFrameworkCore.Infrastructure.IModelCacheKeyFactory
//Singleton      Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IInternalEntityEntryFactory
//Singleton      Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IInternalEntityEntrySubscriber
//Singleton      Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IEntityEntryGraphIterator
//Singleton      Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IEntityGraphAttacher
//Singleton      Microsoft.EntityFrameworkCore.Query.Internal.INodeTypeProviderFactory
//Scoped         Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IKeyPropagator
//Scoped         Microsoft.EntityFrameworkCore.ChangeTracking.Internal.INavigationFixer
//Scoped         Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ILocalViewListener
//Scoped         Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IStateManager
//Scoped         Microsoft.EntityFrameworkCore.Internal.IConcurrencyDetector
//Scoped         Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IInternalEntityEntryNotifier
//Scoped         Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IValueGenerationManager
//Scoped         Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IChangeTrackerFactory
//Scoped         Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IChangeDetector
//Scoped         Microsoft.EntityFrameworkCore.Internal.IDbContextServices
//Scoped         Microsoft.EntityFrameworkCore.Internal.IDbContextDependencies
//Singleton      Microsoft.EntityFrameworkCore.Query.Internal.ICompiledQueryCache
//Scoped         Microsoft.EntityFrameworkCore.Query.Internal.IAsyncQueryProvider
//Scoped         Microsoft.EntityFrameworkCore.Query.Internal.IQueryCompiler
//Singleton      Microsoft.EntityFrameworkCore.Query.Internal.IQueryAnnotationExtractor
//Scoped         Microsoft.EntityFrameworkCore.Query.Internal.IQueryOptimizer
//Singleton      Microsoft.EntityFrameworkCore.Query.Internal.IEntityTrackingInfoFactory
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ITaskBlockingExpressionVisitor
//Scoped         Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.IEntityResultFindingExpressionVisitorFactory
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.IMemberAccessBindingExpressionVisitorFactory
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.INavigationRewritingExpressionVisitorFactory
//Singleton      Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.IQuerySourceTracingExpressionVisitorFactory
//Scoped         Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.IRequiresMaterializationExpressionVisitorFactory
//Scoped         Microsoft.EntityFrameworkCore.Query.IResultOperatorHandler
//Singleton      Microsoft.EntityFrameworkCore.Internal.ISingletonOptionsInitialzer
//Singleton      Microsoft.EntityFrameworkCore.Diagnostics.IDiagnosticsLogger`1
//Singleton Microsoft.EntityFrameworkCore.Diagnostics.ILoggingOptions
//Singleton      Microsoft.EntityFrameworkCore.Infrastructure.ISingletonOptions
//Scoped         Microsoft.EntityFrameworkCore.Metadata.IModel
//Scoped         Microsoft.EntityFrameworkCore.Internal.ICurrentDbContext
//Scoped         Microsoft.EntityFrameworkCore.Infrastructure.IDbContextOptions
//Scoped         Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IEntityStateListener
//Scoped         Microsoft.EntityFrameworkCore.ChangeTracking.Internal.INavigationListener
//Scoped         Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IKeyListener
//Scoped         Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IQueryTrackingListener
//Scoped         Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IPropertyListener
//Scoped         Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IEntityStateListener
//Scoped         Microsoft.EntityFrameworkCore.Infrastructure.IResettableService
//Scoped         Microsoft.EntityFrameworkCore.Infrastructure.IResettableService
//Singleton      Microsoft.EntityFrameworkCore.Storage.DatabaseProviderDependencies
//Singleton      Microsoft.EntityFrameworkCore.Query.ResultOperatorHandlerDependencies
//Singleton      Microsoft.EntityFrameworkCore.Infrastructure.ModelSourceDependencies
//Singleton      Microsoft.EntityFrameworkCore.ValueGeneration.ValueGeneratorCacheDependencies
//Singleton      Microsoft.EntityFrameworkCore.Infrastructure.ModelValidatorDependencies
//Singleton      Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.CoreConventionSetBuilderDependencies
//Scoped         Microsoft.EntityFrameworkCore.Storage.ExecutionStrategyDependencies
//Scoped         Microsoft.EntityFrameworkCore.Query.CompiledQueryCacheKeyGeneratorDependencies
//Scoped         Microsoft.EntityFrameworkCore.Query.QueryContextDependencies
//Scoped         Microsoft.EntityFrameworkCore.ValueGeneration.ValueGeneratorSelectorDependencies
//Scoped         Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitorDependencies
//Scoped         Microsoft.EntityFrameworkCore.Storage.DatabaseDependencies
//Scoped         Microsoft.EntityFrameworkCore.Infrastructure.ModelCustomizerDependencies
//Scoped         Microsoft.EntityFrameworkCore.Infrastructure.ModelCacheKeyFactoryDependencies
//Scoped         Microsoft.EntityFrameworkCore.Query.Internal.QueryCompilationContextDependencies
//Singleton      Microsoft.EntityFrameworkCore.DbContextOptions<Aquirrel.EntityFramework.Test.TestDbContext>
//Singleton Microsoft.EntityFrameworkCore.DbContextOptions
//Singleton Microsoft.EntityFrameworkCore.Infrastructure.IModelCustomizer
//Singleton      Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ICoreConventionSetBuilder
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值