using System; using System.Linq; using Infrastructure; using Infrastructure.Extensions; using Infrastructure.Utilities; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OpenAuth.Repository.Domain; using OpenAuth.Repository.QueryObj; namespace OpenAuth.Repository { public partial class OpenAuthDBContext : DbContext { private ILoggerFactory _LoggerFactory; private IHttpContextAccessor _httpContextAccessor; private IConfiguration _configuration; private IOptions _appConfiguration; public OpenAuthDBContext(DbContextOptions options, ILoggerFactory loggerFactory, IHttpContextAccessor httpContextAccessor, IConfiguration configuration, IOptions appConfiguration) : base(options) { _LoggerFactory = loggerFactory; _httpContextAccessor = httpContextAccessor; _configuration = configuration; _appConfiguration = appConfiguration; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.EnableSensitiveDataLogging(true); //允许打印参数 optionsBuilder.UseLoggerFactory(_LoggerFactory); InitTenant(optionsBuilder); base.OnConfiguring(optionsBuilder); } //初始化多租户信息,根据租户id调整数据库 private void InitTenant(DbContextOptionsBuilder optionsBuilder) { var tenantId = _httpContextAccessor.GetTenantId(); string connect = _configuration.GetConnectionString(tenantId); if (string.IsNullOrEmpty(connect)) { throw new Exception($"未能找到租户{tenantId}对应的连接字符串信息"); } //这个地方如果用IOption,在单元测试的时候会获取不到AppSetting的值😅 var dbtypes = _configuration.GetSection("AppSetting:DbTypes").GetChildren() .ToDictionary(x => x.Key, x => x.Value); var dbType = dbtypes[tenantId]; if (dbType == Define.DBTYPE_SQLSERVER) { optionsBuilder.UseSqlServer(connect); } else if (dbType == Define.DBTYPE_MYSQL) //mysql { optionsBuilder.UseMySql(connect, new MySqlServerVersion(new Version(8, 0, 11))); } else if (dbType == Define.DBTYPE_PostgreSQL) //PostgreSQL { optionsBuilder.UseNpgsql(connect); } else { optionsBuilder.UseOracle(connect, options => options.UseOracleSQLCompatibility("11")); } } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity() .HasKey(c => new { c.Id }); modelBuilder.Entity().HasNoKey(); modelBuilder.Entity().HasNoKey(); //converting between PostgreSQL smallint and .NET Boolean types if (Database.ProviderName == "Npgsql.EntityFrameworkCore.PostgreSQL" || Database.ProviderName == "Oracle.EntityFrameworkCore") { var boolToSmallIntConverter = new ValueConverter( v => v ? (short)1 : (short)0, v => v != 0); foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { foreach (var property in entityType.GetProperties()) { if (property.ClrType == typeof(bool) || property.ClrType == typeof(bool?)) { property.SetValueConverter(boolToSmallIntConverter); } //解决PostgreSQL时间戳问题 if (Database.ProviderName == "Npgsql.EntityFrameworkCore.PostgreSQL" && property.ClrType == typeof(DateTime)) { property.SetValueConverter(new ValueConverter( v => v.ToLocalTime(), v => DateTime.SpecifyKind(v, DateTimeKind.Local))); } } } } // Oracle和PostgreSQL将所有属性映射到大写/小写列名 foreach (var entity in modelBuilder.Model.GetEntityTypes()) { if (Database.ProviderName == "Oracle.EntityFrameworkCore") { entity.SetTableName(entity.GetTableName().ToUpper()); } else if (Database.ProviderName == "Npgsql.EntityFrameworkCore.PostgreSQL" || Database.ProviderName == "Pomelo.EntityFrameworkCore.MySql") { entity.SetTableName(entity.GetTableName().ToLower()); } foreach (var property in entity.GetProperties()) { var storeObject = StoreObjectIdentifier.Create(entity, StoreObjectType.Table); if (storeObject.HasValue) { if (Database.ProviderName == "Oracle.EntityFrameworkCore") { property.SetColumnName(property.GetColumnName(storeObject.Value).ToUpper()); } else if (Database.ProviderName == "Npgsql.EntityFrameworkCore.PostgreSQL" || Database.ProviderName == "Pomelo.EntityFrameworkCore.MySql") { property.SetColumnName(property.GetColumnName(storeObject.Value).ToLower()); } } } } } public virtual DbSet Applications { get; set; } public virtual DbSet Categories { get; set; } public virtual DbSet CategoryTypes { get; set; } public virtual DbSet FlowInstances { get; set; } public virtual DbSet FlowInstanceOperationHistorys { get; set; } public virtual DbSet FlowInstanceTransitionHistorys { get; set; } public virtual DbSet FlowSchemes { get; set; } public virtual DbSet
Forms { get; set; } public virtual DbSet Modules { get; set; } public virtual DbSet ModuleElements { get; set; } public virtual DbSet Orgs { get; set; } public virtual DbSet Relevances { get; set; } public virtual DbSet Resources { get; set; } public virtual DbSet Roles { get; set; } public virtual DbSet Users { get; set; } public virtual DbSet UploadFiles { get; set; } public virtual DbSet SysPrinterPlans { get; set; } public virtual DbSet FrmLeaveReqs { get; set; } public virtual DbSet SysLogs { get; set; } public virtual DbSet SysMessages { get; set; } public virtual DbSet DataPrivilegeRules { get; set; } public virtual DbSet WmsInboundOrderDtbls { get; set; } public virtual DbSet WmsInboundOrderTbls { get; set; } public virtual DbSet OpenJobs { get; set; } public virtual DbSet BuilderTables { get; set; } public virtual DbSet BuilderTableColumns { get; set; } //非数据库表格 public virtual DbSet QueryStringObjs { get; set; } public virtual DbSet SysTableColumns { get; set; } } }