public override string GetConnectionString()
        {
            if (_serviceProvider == null)
            {
                IConfiguration configuration = Singleton <IConfiguration> .Instance;
                string         str           = configuration["OSharp:DbContexts:PostgreSql:ConnectionString"];
                return(str);
            }
            OsharpOptions          options        = _serviceProvider.GetOSharpOptions();
            OsharpDbContextOptions contextOptions = options.GetDbContextOptions(typeof(DefaultDbContext));

            if (contextOptions == null)
            {
                throw new OsharpException($"上下文“{typeof(DefaultDbContext)}”的配置信息不存在");
            }
            return(contextOptions.ConnectionString);
        }
        public override bool LazyLoadingProxiesEnabled()
        {
            if (_serviceProvider == null)
            {
                IConfiguration configuration = Singleton <IConfiguration> .Instance;
                return(configuration["OSharp:DbContexts:PostgreSql:LazyLoadingProxiesEnabled"].CastTo(false));
            }
            OsharpOptions          options        = _serviceProvider.GetOSharpOptions();
            OsharpDbContextOptions contextOptions = options.GetDbContextOptions(typeof(DefaultDbContext));

            if (contextOptions == null)
            {
                throw new OsharpException($"上下文“{typeof(DefaultDbContext)}”的配置信息不存在");
            }

            return(contextOptions.LazyLoadingProxiesEnabled);
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        /// <summary>
        /// 获取指定上下文类型的上下文实例
        /// </summary>
        /// <returns></returns>
        public IUnitOfWork GetDbContextUnitOfWork(Type dbContextType)
        {
            if (!dbContextType.IsBaseOn(typeof(DbContext)))
            {
                throw new OsharpException($"类型 {dbContextType} 不是数据上下文类型");
            }
            OsharpDbContextOptions dbContextOptions = GetDbContextResolveOptions(dbContextType);
            IUnitOfWork            unitOfWork       = _scopedDictionary.GetConnUnitOfWork(dbContextOptions.ConnectionString);

            if (unitOfWork != null)
            {
                _logger.LogDebug($"由上下文 {dbContextType} 的连接串获取到已存在的工作单元,工作单元标识:{unitOfWork.GetHashCode()}");
                return(unitOfWork);
            }
            unitOfWork = ActivatorUtilities.CreateInstance <UnitOfWork>(ServiceProvider);
            _scopedDictionary.SetConnUnitOfWork(dbContextOptions.ConnectionString, unitOfWork);
            return(unitOfWork);
        }
Пример #5
0
        /// <summary>
        /// 获取指定类型的上下文实例
        /// </summary>
        /// <param name="dbContextType">上下文类型</param>
        /// <returns></returns>
        public IDbContext GetDbContext(Type dbContextType)
        {
            DbContextBase dbContext = (DbContextBase)_provider.GetService(dbContextType);

            if (!dbContext.ExistsRelationalDatabase())
            {
                throw new OsharpException($"数据上下文 {dbContext.GetType().FullName} 的数据库不存在,请通过 Migration 功能进行数据迁移创建数据库。");
            }

            OsharpDbContextOptions dbContextOptions = _provider.GetOSharpOptions().GetDbContextOptions(dbContextType);
            ScopedDictionary       scopedDictionary = _provider.GetService <ScopedDictionary>();

            _connection = dbContext.Database.GetDbConnection();
            scopedDictionary.TryAdd($"DbConnection_{dbContextOptions.ConnectionString}", _connection);

            dbContext.UnitOfWork = this;
            _dbContexts.Add(dbContext);

            return(dbContext);
        }
Пример #6
0
        /// <summary>
        /// 获取指定数据上下文类型的数据库连接字符串
        /// </summary>
        /// <param name="dbContextType">数据上下文类型</param>
        /// <returns></returns>
        public virtual string GetConnectionString(Type dbContextType)
        {
            OsharpDbContextOptions dbContextOptions = _dbContexts.Values.FirstOrDefault(m => m.DbContextType == dbContextType);

            if (dbContextOptions == null)
            {
                throw new OsharpException($"数据上下文“{dbContextType}”的数据上下文配置信息不存在");
            }

            bool isSlave = _masterSlavePolicy.IsToSlaveDatabase(dbContextOptions);

            if (!isSlave)
            {
                return(dbContextOptions.ConnectionString);
            }

            SlaveDatabaseOptions[] slaves = dbContextOptions.Slaves;
            ISlaveDatabaseSelector slaveDatabaseSelector = _slaveDatabaseSelectors.LastOrDefault(m => m.Name == dbContextOptions.SlaveSelectorName)
                                                           ?? _slaveDatabaseSelectors.First(m => m.Name == "Weight");
            SlaveDatabaseOptions slave = slaveDatabaseSelector.Select(slaves);

            return(slave.ConnectionString);
        }
Пример #7
0
        /// <summary>
        /// 应用模块服务
        /// </summary>
        /// <param name="provider">服务提供者</param>
        public override void UsePack(IServiceProvider provider)
        {
            OsharpOptions          options        = provider.GetOSharpOptions();
            OsharpDbContextOptions contextOptions = options.GetDbContextOptions(typeof(TDbContext));

            if (contextOptions?.DatabaseType != DatabaseType)
            {
                return;
            }

            using (IServiceScope scope = provider.CreateScope())
            {
                TDbContext context = CreateDbContext(scope.ServiceProvider);
                if (context != null && contextOptions.AutoMigrationEnabled)
                {
                    context.CheckAndMigration();
                    DbContextModelCache modelCache = scope.ServiceProvider.GetService <DbContextModelCache>();
                    modelCache?.Set(context.GetType(), context.Model);
                }
            }

            IsEnabled = true;
        }
Пример #8
0
        /// <summary>
        /// 应用模块服务
        /// </summary>
        /// <param name="provider">服务提供者</param>
        public override void UsePack(IServiceProvider provider)
        {
            OsharpOptions          options        = provider.GetOSharpOptions();
            OsharpDbContextOptions contextOptions = options.GetDbContextOptions(typeof(TDbContext));

            if (contextOptions?.DatabaseType != DatabaseType)
            {
                return;
            }

            ILogger logger = provider.GetLogger(GetType());

            using (IServiceScope scope = provider.CreateScope())
            {
                TDbContext context = CreateDbContext(scope.ServiceProvider);
                if (context != null && contextOptions.AutoMigrationEnabled)
                {
                    context.CheckAndMigration(logger);
                    DbContextModelCache modelCache = scope.ServiceProvider.GetService <DbContextModelCache>();
                    modelCache?.Set(context.GetType(), context.Model);
                }
            }

            //初始化种子数据,只初始化当前上下文的种子数据
            IEntityManager entityManager = provider.GetService <IEntityManager>();

            Type[] entityTypes = entityManager.GetEntityRegisters(typeof(TDbContext)).Select(m => m.EntityType).Distinct().ToArray();
            IEnumerable <ISeedDataInitializer> seedDataInitializers = provider.GetServices <ISeedDataInitializer>()
                                                                      .Where(m => entityTypes.Contains(m.EntityType)).OrderBy(m => m.Order);

            foreach (ISeedDataInitializer initializer in seedDataInitializers)
            {
                initializer.Initialize();
            }

            IsEnabled = true;
        }
Пример #9
0
        /// <summary>
        /// 是否前往从数据库
        /// </summary>
        /// <param name="options">数据上下文选项</param>
        /// <returns></returns>
        public bool IsToSlaveDatabase(OsharpDbContextOptions options)
        {
            SlaveDatabaseOptions[] slaves = options.Slaves;
            if (slaves.IsNullOrEmpty())
            {
                return(false);
            }

            //允许工作单元事务,走主库
            if (_unitOfWork.IsEnabledTransaction)
            {
                return(false);
            }

            // 在Function显式配置走从库,才走从库
            IFunction function = _scopedDict.Function;

            if (function == null || !function.IsSlaveDatabase)
            {
                return(false);
            }

            return(true);
        }