/// <summary> /// 获取指定数据上下文类型<typeparamref name="TEntity"/>的实例,并将同数据库连接字符串的上下文实例进行分组归类 /// </summary> /// <typeparam name="TEntity">实体类型</typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <returns><typeparamref name="TEntity"/>所属上下文类的实例</returns> public IDbContext GetDbContext <TEntity, TKey>() where TEntity : IEntity <TKey> where TKey : IEquatable <TKey> { IEntityConfigurationTypeFinder typeFinder = _serviceProvider.GetService <IEntityConfigurationTypeFinder>(); Type entityType = typeof(TEntity); Type dbContextType = typeFinder.GetDbContextTypeForEntity(entityType); OSharpDbContextOptions dbContextOptions = GetDbContextResolveOptions(dbContextType); DbContextResolveOptions resolveOptions = new DbContextResolveOptions(dbContextOptions); //已存在上下文对象,直接返回 DbContextBase dbContext = _dbContextMamager.Get(dbContextType, resolveOptions.ConnectionString); if (dbContext != null) { return(dbContext); } IDbContextResolver contextResolver = _serviceProvider.GetService <IDbContextResolver>(); dbContext = (DbContextBase)contextResolver.Resolve(resolveOptions); if (!dbContext.ExistsRelationalDatabase()) { throw new OsharpException($"数据上下文“{dbContext.GetType().FullName}”的数据库不存在,请通过 Migration 功能进行数据迁移创建数据库。"); } if (resolveOptions.ExistingConnection == null) { resolveOptions.ExistingConnection = dbContext.Database.GetDbConnection(); } _dbContextMamager.Add(dbContextOptions.ConnectionString, dbContext); return(dbContext); }
/// <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> /// 获取指定实体所在的工作单元对象 /// </summary> /// <param name="entityType">实体类型</param> /// <returns>工作单元对象</returns> public IUnitOfWork GetUnitOfWork(Type entityType) { if (!entityType.IsEntityType()) { throw new OsharpException($"类型“{entityType}”不是实体类型"); } IUnitOfWork unitOfWork = _entityTypeUnitOfWorks.GetOrDefault(entityType); if (unitOfWork != null) { return(unitOfWork); } IEntityConfigurationTypeFinder typeFinder = _serviceProvider.GetService <IEntityConfigurationTypeFinder>(); Type dbContextType = typeFinder.GetDbContextTypeForEntity(entityType); if (dbContextType == null) { throw new OsharpException($"实体类“{entityType}”的所属上下文类型无法找到"); } OSharpDbContextOptions dbContextOptions = GetDbContextResolveOptions(dbContextType); DbContextResolveOptions resolveOptions = new DbContextResolveOptions(dbContextOptions); unitOfWork = _connStringUnitOfWorks.GetOrDefault(resolveOptions.ConnectionString); if (unitOfWork != null) { return(unitOfWork); } unitOfWork = ActivatorUtilities.CreateInstance <UnitOfWork>(_serviceProvider, resolveOptions); _entityTypeUnitOfWorks.TryAdd(entityType, unitOfWork); _connStringUnitOfWorks.TryAdd(resolveOptions.ConnectionString, unitOfWork); return(unitOfWork); }
/// <summary> /// 获取指定数据上下文类型<typeparamref name="TEntity"/>的实例 /// </summary> /// <typeparam name="TEntity">实体类型</typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <returns><typeparamref name="TEntity"/>所属上下文类的实例</returns> public IDbContext GetDbContext <TEntity, TKey>() where TEntity : IEntity <TKey> where TKey : IEquatable <TKey> { IEntityConfigurationTypeFinder typeFinder = _serviceProvider.GetService <IEntityConfigurationTypeFinder>(); Type entityType = typeof(TEntity); Type dbContextType = typeFinder.GetDbContextTypeForEntity(entityType); DbContext dbContext; OSharpDbContextOptions dbContextOptions = GetDbContextResolveOptions(dbContextType); DbContextResolveOptions resolveOptions = new DbContextResolveOptions(dbContextOptions); IDbContextResolver contextResolver = _serviceProvider.GetService <IDbContextResolver>(); ActiveTransactionInfo transInfo = ActiveTransactionInfos.GetOrDefault(resolveOptions.ConnectionString); //连接字符串的事务不存在,添加起始上下文事务信息 if (transInfo == null) { resolveOptions.ExistingConnection = null; dbContext = contextResolver.Resolve(resolveOptions); RelationalDatabaseCreator dbCreator; if ((dbCreator = dbContext.GetService <IDatabaseCreator>() as RelationalDatabaseCreator) != null) { if (!dbCreator.Exists()) { throw new OsharpException($"数据上下文“{dbContext.GetType().FullName}”的数据库不存在,请通过 Migration 功能进行数据迁移创建数据库。"); } } IDbContextTransaction transaction = dbContext.Database.BeginTransaction(); transInfo = new ActiveTransactionInfo(transaction, dbContext); ActiveTransactionInfos[resolveOptions.ConnectionString] = transInfo; } else { resolveOptions.ExistingConnection = transInfo.DbContextTransaction.GetDbTransaction().Connection; //相同连接串相同上下文类型并且已存在对象,直接返回上下文对象 if (transInfo.StarterDbContext.GetType() == resolveOptions.DbContextType) { return(transInfo.StarterDbContext as IDbContext); } dbContext = contextResolver.Resolve(resolveOptions); if (dbContext.IsRelationalTransaction()) { dbContext.Database.UseTransaction(transInfo.DbContextTransaction.GetDbTransaction()); } else { dbContext.Database.BeginTransaction(); } transInfo.AttendedDbContexts.Add(dbContext); } return(dbContext as IDbContext); }
/// <summary> /// 获取指定类型的数据上下文对象 /// </summary> /// <param name="resolveOptions">上下文解析选项</param> /// <returns></returns> public DbContext 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} 实例"); } DbContextOptions options = builderCreator.Create(resolveOptions.ConnectionString, resolveOptions.ExistingConnection).Options; DbContext context = ActivatorUtilities.CreateInstance(_serviceProvider, dbContextType, options) as DbContext; if (context == null) { throw new OsharpException($"实例化数据上下文“{dbContextType.AssemblyQualifiedName}”失败"); } return(context); }
/// <summary> /// 获取指定数据上下文类型<typeparamref name="TEntity"/>的实例 /// </summary> /// <typeparam name="TEntity">实体类型</typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <returns><typeparamref name="TEntity"/>所属上下文类的实例</returns> public IDbContext GetDbContext <TEntity, TKey>() where TEntity : IEntity <TKey> where TKey : IEquatable <TKey> { IEntityConfigurationTypeFinder typeFinder = _serviceProvider.GetService <IEntityConfigurationTypeFinder>(); Type dbContextType = typeFinder.GetDbContextTypeForEntity(typeof(TEntity)); DbContext dbContext; OsharpDbContextConfig dbContextConfig = GetDbContextResolveOptionsConfig(dbContextType); DbContextResolveOptions resolveOptions = new DbContextResolveOptions(dbContextConfig); IDbContextResolver contextResolver = _serviceProvider.GetService <IDbContextResolver>(); ActiveTransactionInfo transInfo = ActiveTransactionInfos.GetOrDefault(resolveOptions.ConnectionString); //连接字符串的事务不存在,添加起始上下文事务信息 if (transInfo == null) { resolveOptions.ExistingConnection = null; dbContext = contextResolver.Resolve(resolveOptions); IDbContextTransaction transaction = dbContext.Database.BeginTransaction(); transInfo = new ActiveTransactionInfo(transaction, dbContext); ActiveTransactionInfos[resolveOptions.ConnectionString] = transInfo; } else { resolveOptions.ExistingConnection = transInfo.DbContextTransaction.GetDbTransaction().Connection; dbContext = contextResolver.Resolve(resolveOptions); if (dbContext.IsRelationalTransaction()) { dbContext.Database.UseTransaction(transInfo.DbContextTransaction.GetDbTransaction()); } else { dbContext.Database.BeginTransaction(); } transInfo.AttendedDbContexts.Add(dbContext); } return(dbContext as IDbContext); }
/// <summary> /// 初始化一个<see cref="UnitOfWork"/>类型的新实例 /// </summary> public UnitOfWork(IServiceProvider serviceProvider, DbContextResolveOptions resolveOptions) { _serviceProvider = serviceProvider; _resolveOptions = resolveOptions; }