Пример #1
0
        /// <summary>
        /// 获取指定实体所在的工作单元对象
        /// </summary>
        /// <param name="entityType">实体类型</param>
        /// <returns>工作单元对象</returns>
        public IUnitOfWork GetUnitOfWork(Type entityType)
        {
            if (!entityType.IsEntityType())
            {
                throw new HybridException($"类型“{entityType}”不是实体类型");
            }

            IUnitOfWork unitOfWork = _scopedDictionary.GetEntityUnitOfWork(entityType);

            if (unitOfWork != null)
            {
                return(unitOfWork);
            }

            IEntityManager entityManager = ServiceProvider.GetService <IEntityManager>();
            Type           dbContextType = entityManager.GetDbContextTypeForEntity(entityType);

            if (dbContextType == null)
            {
                throw new HybridException($"实体类“{entityType}”的所属上下文类型无法找到");
            }
            HybridDbContextOptions dbContextOptions = GetDbContextResolveOptions(dbContextType);

            unitOfWork = _scopedDictionary.GetConnUnitOfWork(dbContextOptions.ConnectionString);
            if (unitOfWork != null)
            {
                return(unitOfWork);
            }
            unitOfWork = ActivatorUtilities.CreateInstance <UnitOfWork>(ServiceProvider);
            _scopedDictionary.SetEntityUnitOfWork(entityType, unitOfWork);
            _scopedDictionary.SetConnUnitOfWork(dbContextOptions.ConnectionString, unitOfWork);

            return(unitOfWork);
        }
Пример #2
0
        /// <summary>
        /// 获取指定数据实体的上下文类型
        /// </summary>
        /// <param name="entityType">实体类型</param>
        /// <returns>实体所属上下文实例</returns>
        public IDbContext GetDbContext(Type entityType)
        {
            if (!entityType.IsEntityType())
            {
                throw new HybridException($"类型“{entityType}”不是实体类型");
            }

            IEntityManager manager       = _serviceProvider.GetService <IEntityManager>();
            Type           dbContextType = manager.GetDbContextTypeForEntity(entityType);

            //已存在上下文对象,直接返回
            DbContextBase dbContext = _dbContexts.FirstOrDefault(m => m.GetType() == dbContextType);

            if (dbContext != null)
            {
                return(dbContext);
            }

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

            _dbContextOptions = _serviceProvider.GetHybridOptions().GetDbContextOptions(dbContextType);
            ScopedDictionary scopedDictionary = _serviceProvider.GetService <ScopedDictionary>();

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

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

            return(dbContext);
        }
Пример #3
0
 /// <summary>
 /// 初始化一个<see cref="DbContextBase"/>类型的新实例
 /// </summary>
 protected DbContextBase(DbContextOptions options, IEntityManager entityManager, IServiceProvider serviceProvider)
     : base(options)
 {
     _entityManager   = entityManager;
     _serviceProvider = serviceProvider;
     _hybridDbOptions = serviceProvider?.GetHybridOptions()?.DbContexts?.Values.FirstOrDefault(m => m.DbContextType == GetType());
     _logger          = serviceProvider?.GetLogger(GetType());
 }
Пример #4
0
        /// <summary>
        /// 获取指定实体类型的Sql执行器
        /// </summary>
        public static ISqlExecutor <TEntity, TKey> GetSqlExecutor <TEntity, TKey>(this IUnitOfWorkManager unitOfWorkManager) where TEntity : IEntity <TKey>
        {
            HybridDbContextOptions options                  = unitOfWorkManager.GetDbContextResolveOptions(typeof(TEntity));
            DatabaseType           databaseType             = options.DatabaseType;
            IList <ISqlExecutor <TEntity, TKey> > executors = unitOfWorkManager.ServiceProvider.GetServices <ISqlExecutor <TEntity, TKey> >().ToList();

            return(executors.FirstOrDefault(m => m.DatabaseType == databaseType));
        }
Пример #5
0
        /// <summary>
        /// 获取数据上下文选项
        /// </summary>
        /// <param name="dbContextType">数据上下文类型</param>
        /// <returns>数据上下文选项</returns>
        public HybridDbContextOptions GetDbContextResolveOptions(Type dbContextType)
        {
            HybridDbContextOptions dbContextOptions = ServiceProvider.GetHybridOptions()?.GetDbContextOptions(dbContextType);

            if (dbContextOptions == null)
            {
                throw new HybridException($"无法找到数据上下文“{dbContextType}”的配置信息");
            }
            return(dbContextOptions);
        }
Пример #6
0
        /// <summary>
        /// 获取指定实体类型的数据上下文选项
        /// </summary>
        public static HybridDbContextOptions GetDbContextResolveOptions(this IUnitOfWorkManager unitOfWorkManager, Type entityType)
        {
            Type dbContextType = unitOfWorkManager.GetDbContextType(entityType);
            HybridDbContextOptions dbContextOptions = unitOfWorkManager.ServiceProvider.GetHybridOptions()?.GetDbContextOptions(dbContextType);

            if (dbContextOptions == null)
            {
                throw new HybridException($"无法找到数据上下文“{dbContextType}”的配置信息");
            }
            return(dbContextOptions);
        }
        public override bool LazyLoadingProxiesEnabled()
        {
            if (_serviceProvider == null)
            {
                IConfiguration configuration = Singleton <IConfiguration> .Instance;
                return(configuration["Hybrid:DbContexts:PostgreSql:LazyLoadingProxiesEnabled"].CastTo(false));
            }
            HybridOptions          options        = _serviceProvider.GetHybridOptions();
            HybridDbContextOptions contextOptions = options.GetDbContextOptions(typeof(DefaultDbContext));

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

            return(contextOptions.LazyLoadingProxiesEnabled);
        }
        public override string GetConnectionString()
        {
            if (_serviceProvider == null)
            {
                IConfiguration configuration = Singleton <IConfiguration> .Instance;
                string         str           = configuration["Hybrid:DbContexts:PostgreSql:ConnectionString"];
                return(str);
            }
            HybridOptions          options        = _serviceProvider.GetHybridOptions();
            HybridDbContextOptions contextOptions = options.GetDbContextOptions(typeof(DefaultDbContext));

            if (contextOptions == null)
            {
                throw new HybridException($"上下文“{typeof(DefaultDbContext)}”的配置信息不存在");
            }
            return(contextOptions.ConnectionString);
        }
        /// <summary>
        /// 将基于Hybrid数据上下文基类<see cref="DbContextBase"/>上下文类型添加到服务集合中
        /// </summary>
        /// <typeparam name="TDbContext">基于Hybrid数据上下文基类<see cref="DbContextBase"/>上下文类型</typeparam>
        /// <param name="services">依赖注入服务集合</param>
        /// <param name="optionsAction">数据库选项创建配置,将在内置配置后运行</param>
        /// <returns>依赖注入服务集合</returns>
        public static IServiceCollection AddHybridDbContext <TDbContext>(this IServiceCollection services, Action <IServiceProvider, DbContextOptionsBuilder> optionsAction = null) where TDbContext : DbContextBase
        {
            services.AddDbContext <TDbContext>((provider, builder) =>
            {
                Type dbContextType          = typeof(TDbContext);
                HybridOptions hybridOptions = provider.GetHybridOptions();
                HybridDbContextOptions hybridDbContextOptions = hybridOptions?.GetDbContextOptions(dbContextType);
                if (hybridDbContextOptions == null)
                {
                    throw new HybridException($"无法找到数据上下文“{dbContextType.DisplayName()}”的配置信息");
                }

                //启用延迟加载
                if (hybridDbContextOptions.LazyLoadingProxiesEnabled)
                {
                    builder = builder.UseLazyLoadingProxies();
                }
                DatabaseType databaseType = hybridDbContextOptions.DatabaseType;

                //处理数据库驱动差异处理
                IDbContextOptionsBuilderDriveHandler driveHandler = provider.GetServices <IDbContextOptionsBuilderDriveHandler>()
                                                                    .FirstOrDefault(m => m.Type == databaseType);
                if (driveHandler == null)
                {
                    throw new HybridException($"无法解析类型为“{databaseType}”的 {typeof(IDbContextOptionsBuilderDriveHandler).DisplayName()} 实例");
                }

                ScopedDictionary scopedDictionary = provider.GetService <ScopedDictionary>();
                string key = $"DnConnection_{hybridDbContextOptions.ConnectionString}";
                DbConnection existingDbConnection = scopedDictionary.GetValue <DbConnection>(key);
                builder = driveHandler.Handle(builder, hybridDbContextOptions.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);
        }
Пример #10
0
        /// <summary>
        /// 应用模块服务
        /// </summary>
        /// <param name="provider">服务提供者</param>
        public override void UseModule(IServiceProvider provider)
        {
            HybridOptions          options        = provider.GetHybridOptions();
            HybridDbContextOptions 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;
        }