扩展entity framework core 实现默认字符串长度,decimal精度,entity自动注册和配置
文章以efcore 2.0.0-preview2.测试验证通过。其他版本不保证使用,但是思路不会差太远。源代码,报道越短,事情越严重!文章越短,内容越精悍!
目标:
1.实现entity的自动发现和mapper设置.
2.默认字符串长度,而不是nvarchar(max).
3.decimal设置精度
当然,我们也可以重写dbcontext的OnModelCreating方法,but,我们怎么能这么low呢。必须要用点高级玩意是吧,当然这也是更底层的扩展方式。项目里面有多个dbcontext的话,在这里集中扩展管理比较方便。
在然后,这个RelationalModelCustomizer继承自ModelCustomizer。在联想到efcore未来的版本会支持redis,nosql什么的。到时候估计还回有一个osqlModelCustomizer之类的吧,期待中......
重写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