/// <summary> /// 获取指定类型的数据上下文对象 /// </summary> /// <param name="resolveOptions">上下文解析选项</param> /// <returns></returns> public IDbContext Resolve(DbContextResolveOptions resolveOptions) { Type dbContextType = resolveOptions.DbContextType; IDbContextOptionsBuilderCreator builderCreator = _serviceProvider.GetServices <IDbContextOptionsBuilderCreator>() .FirstOrDefault(m => m.Type == resolveOptions.DatabaseType); if (builderCreator == null) { throw new OsharpException($"无法解析类型为“{resolveOptions.DatabaseType}”的 {typeof(IDbContextOptionsBuilderCreator).FullName} 实例"); } DbContextOptionsBuilder optionsBuilder = builderCreator.Create(resolveOptions.ConnectionString, resolveOptions.ExistingConnection); DbContextModelCache modelCache = _serviceProvider.GetService <DbContextModelCache>(); IModel model = modelCache.Get(dbContextType); if (model != null) { optionsBuilder.UseModel(model); } DbContextOptions options = optionsBuilder.Options; //创建上下文实例 if (!(ActivatorUtilities.CreateInstance(_serviceProvider, dbContextType, options) is DbContext context)) { throw new OsharpException($"实例化数据上下文“{dbContextType.AssemblyQualifiedName}”失败"); } return(context as IDbContext); }
/// <summary> /// 构建<see cref="DbContextOptionsBuilder"/>,附加必要的扩展属性 /// </summary> public static DbContextOptionsBuilder BuildDbContextOptionsBuilder <TDbContext>(this IServiceProvider provider, DbContextOptionsBuilder builder) where TDbContext : DbContext { Type dbContextType = typeof(TDbContext); OsharpOptions osharpOptions = provider.GetOSharpOptions(); OsharpDbContextOptions osharpDbContextOptions = osharpOptions?.GetDbContextOptions(dbContextType); if (osharpDbContextOptions == null) { throw new OsharpException($"无法找到数据上下文 {dbContextType.DisplayName()} 的配置信息"); } ILogger logger = provider.GetLogger(typeof(ServiceExtensions)); //启用延迟加载 if (osharpDbContextOptions.LazyLoadingProxiesEnabled) { builder = builder.UseLazyLoadingProxies(); logger.LogDebug($"数据上下文类型 {dbContextType} 应用延迟加载代理"); } DatabaseType databaseType = osharpDbContextOptions.DatabaseType; //处理数据库驱动差异处理 IDbContextOptionsBuilderDriveHandler driveHandler = provider.GetServices <IDbContextOptionsBuilderDriveHandler>() .LastOrDefault(m => m.Type == databaseType); if (driveHandler == null) { throw new OsharpException($"无法解析类型为 {databaseType} 的 {typeof(IDbContextOptionsBuilderDriveHandler).DisplayName()} 实例,是否未在Startup执行AddPack<{databaseType}DefaultDbContextMigrationPack>()"); } //选择主/从数据库连接串 IConnectionStringProvider connectionStringProvider = provider.GetRequiredService <IConnectionStringProvider>(); string connectionString = connectionStringProvider.GetConnectionString(typeof(TDbContext)); ScopedDictionary scopedDictionary = provider.GetRequiredService <ScopedDictionary>(); string key = $"DbConnection_{connectionString}"; DbConnection existingDbConnection = scopedDictionary.GetValue <DbConnection>(key); builder = driveHandler.Handle(builder, connectionString, existingDbConnection); //使用模型缓存 DbContextModelCache modelCache = provider.GetService <DbContextModelCache>(); IModel model = modelCache?.Get(dbContextType); if (model != null) { builder = builder.UseModel(model); } return(builder); }
/// <summary> /// 将基于Osharp数据上下文基类<see cref="DbContextBase"/>上下文类型添加到服务集合中 /// </summary> /// <typeparam name="TDbContext">基于Osharp数据上下文基类<see cref="DbContextBase"/>上下文类型</typeparam> /// <param name="services">依赖注入服务集合</param> /// <param name="optionsAction">数据库选项创建配置,将在内置配置后运行</param> /// <returns>依赖注入服务集合</returns> public static IServiceCollection AddOsharpDbContext <TDbContext>(this IServiceCollection services, Action <IServiceProvider, DbContextOptionsBuilder> optionsAction = null) where TDbContext : DbContextBase { services.AddDbContext <TDbContext>((provider, builder) => { Type dbContextType = typeof(TDbContext); OsharpOptions osharpOptions = provider.GetOSharpOptions(); OsharpDbContextOptions osharpDbContextOptions = osharpOptions?.GetDbContextOptions(dbContextType); if (osharpDbContextOptions == null) { throw new OsharpException($"无法找到数据上下文“{dbContextType.DisplayName()}”的配置信息"); } //启用延迟加载 if (osharpDbContextOptions.LazyLoadingProxiesEnabled) { builder = builder.UseLazyLoadingProxies(); } DatabaseType databaseType = osharpDbContextOptions.DatabaseType; //处理数据库驱动差异处理 IDbContextOptionsBuilderDriveHandler driveHandler = provider.GetServices <IDbContextOptionsBuilderDriveHandler>() .FirstOrDefault(m => m.Type == databaseType); if (driveHandler == null) { throw new OsharpException($"无法解析类型为“{databaseType}”的 {typeof(IDbContextOptionsBuilderDriveHandler).DisplayName()} 实例"); } ScopedDictionary scopedDictionary = provider.GetService <ScopedDictionary>(); string key = $"DnConnection_{osharpDbContextOptions.ConnectionString}"; DbConnection existingDbConnection = scopedDictionary.GetValue <DbConnection>(key); builder = driveHandler.Handle(builder, osharpDbContextOptions.ConnectionString, existingDbConnection); //使用模型缓存 DbContextModelCache modelCache = provider.GetService <DbContextModelCache>(); IModel model = modelCache?.Get(dbContextType); if (model != null) { builder = builder.UseModel(model); } //额外的选项 optionsAction?.Invoke(provider, builder); }); return(services); }