using IRaCIS.Core.Domain.Models; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using System; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.ChangeTracking; using System.Reflection; using EntityFramework.Exceptions.SqlServer; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infra.EFCore.ValueGenerator; using MassTransit; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.ValueGeneration; using UserTypeGroup = IRaCIS.Core.Domain.Models.UserTypeGroup; using IRaCIS.Core.Infra.EFCore.Common; using IRaCIS.Core.Infra.EFCore.Common.Dto; namespace IRaCIS.Core.Infra.EFCore { public class IRaCISDBContext : DbContext { public readonly IUserInfo _userInfo; //private readonly IAuditingData _auditingData; // 在控制台 //public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); }); // 调试窗口 public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddDebug(); }); public IRaCISDBContext(DbContextOptions options, IUserInfo userInfo //IAuditingData auditingData ) : base(options) { _userInfo = userInfo; //this._auditingData = auditingData; //_configuration = configuration; } //比数据库上下文构造函数先执行 不能构造函数注入的方式使用配置文件 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseLoggerFactory(MyLoggerFactory) .ReplaceService(); optionsBuilder.UseExceptionProcessor(); //var config = new ConfigurationBuilder() // .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true).Build(); //connectionString = config.GetSection("ConnectionStrings:RemoteNew").Value; //optionsBuilder.AddInterceptors(new AuditingInterceptor(connectionString)); } #region IModelCacheKeyFactory public class DynamicModelCacheKeyFactoryDesignTimeSupport : IModelCacheKeyFactory { public object Create(DbContext context, bool designTime) => context is IRaCISDBContext dynamicContext ? (context.GetType(), dynamicContext._userInfo.IsEn_Us, designTime) : (object)context.GetType(); public object Create(DbContext context) => Create(context, false); } #endregion protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity(builder => { builder.HasBaseType((Type)null); builder.ToView(null); builder.HasNoKey(); }); //modelBuilder.HasDbFunction(typeof(DbContext).GetMethod(nameof(GetTableList))); modelBuilder.Entity().HasMany(t => t.VisitTaskList).WithOne(t => t.TaskAllocationRule).HasForeignKey(t=>t.DoctorUserId).HasPrincipalKey(u=>u.DoctorUserId); modelBuilder.Entity().HasMany(t => t.ChildList).WithOne(t => t.Parent); if (_userInfo.IsEn_Us) { modelBuilder.Entity().Property(t => t.MappedValue).HasColumnName(nameof(Domain.Models.Dictionary.Value)); } else { modelBuilder.Entity().Property(t => t.MappedValue).HasColumnName(nameof(Domain.Models.Dictionary.ValueCN)); } //遍历实体模型手动配置 var typesToRegister = Assembly.GetExecutingAssembly().GetTypes().Where(q => q.GetInterface(typeof(IEntityTypeConfiguration<>).FullName) != null); foreach (var type in typesToRegister) { dynamic configurationInstance = Activator.CreateInstance(type); modelBuilder.ApplyConfiguration(configurationInstance); } base.OnModelCreating(modelBuilder); foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { // 软删除配置 if (typeof(ISoftDelete).IsAssignableFrom(entityType.ClrType)) { entityType.AddSoftDeleteQueryFilter(); } if (typeof(Entity).IsAssignableFrom(entityType.ClrType)) { modelBuilder.Entity(entityType.ClrType).Property(nameof(Entity.Id)).HasValueGenerator(); } } } #region public IQueryable GetTableList() { return Set().FromSqlRaw("EXEC dbo.procGetTableList"); } public IQueryable GetTableColumn(string tableName) { return Set().FromSqlRaw($"EXEC dbo.procGetTableColumn {tableName}"); } #endregion #region Doctor public virtual DbSet Dictionary { get; set; } public virtual DbSet Doctor { get; set; } public virtual DbSet DoctorDictionary { get; set; } public virtual DbSet Postgraduate { get; set; } public virtual DbSet Education { get; set; } public virtual DbSet ResearchPublications { get; set; } public virtual DbSet TrialExperience { get; set; } public virtual DbSet UserDoctor { get; set; } public virtual DbSet Vacation { get; set; } public virtual DbSet Attachment { get; set; } public virtual DbSet TrialExperienceCriteria { get; set; } #endregion #region Enroll public virtual DbSet DoctorWorkload { get; set; } public virtual DbSet IntoGroup { get; set; } public virtual DbSet EnrollDetails { get; set; } #endregion #region Reading public virtual DbSet ReadingPeriodSet { get; set; } public virtual DbSet ReadingPeriodPlan { get; set; } public virtual DbSet ReadingClinicalData { get; set; } public virtual DbSet ReadingClinicalDataPDF { get; set; } public virtual DbSet ReadModule { get; set; } public virtual DbSet ReadModuleView { get; set; } public virtual DbSet ClinicalDataTrialSet { get; set; } public virtual DbSet ClinicalDataSystemSet { get; set; } #endregion #region Subject and Visit and study public virtual DbSet StudyMonitor { get; set; } public virtual DbSet Subject { get; set; } public virtual DbSet VisitPlans { get; set; } public virtual DbSet VisitPlanInfluenceStudy { get; set; } public virtual DbSet VisitPlanInfluenceStat { get; set; } public virtual DbSet NoneDicomStudyFile { get; set; } public virtual DbSet NoneDicomStudy { get; set; } public virtual DbSet PreviousPDF { get; set; } public virtual DbSet PreviousSurgery { get; set; } public virtual DbSet PreviousOther { get; set; } public virtual DbSet PreviousHistory { get; set; } public virtual DbSet StudyDTF { get; set; } public virtual DbSet DicomStudys { get; set; } public virtual DbSet DicomSeries { get; set; } public virtual DbSet DicomInstances { get; set; } public virtual DbSet ImageShare { get; set; } #endregion #region Management public virtual DbSet VerificationCodes { get; set; } public virtual DbSet MenuFunctions { get; set; } public virtual DbSet Roles { get; set; } public virtual DbSet UserTypeMenuFunction { get; set; } public virtual DbSet Users { get; set; } public virtual DbSet UserRoles { get; set; } public virtual DbSet TrialAudit { get; set; } public virtual DbSet UserType { get; set; } public virtual DbSet SaveChangesAudits { get; set; } #endregion #region Institution public virtual DbSet ResearchCenter { get; set; } public virtual DbSet Hospitals { get; set; } public virtual DbSet CROCompany { get; set; } public virtual DbSet Sponsor { get; set; } #endregion #region Trial public virtual DbSet Trial { get; set; } public virtual DbSet TrialDictionary { get; set; } public virtual DbSet TrialDetail { get; set; } public virtual DbSet UserTrial { get; set; } public virtual DbSet ProjectDictionary { get; set; } public virtual DbSet UserTrialSite { get; set; } public virtual DbSet TrialSite { get; set; } public virtual DbSet Site { get; set; } public virtual DbSet User { get; set; } public virtual DbSet TrialSiteUserSurvey { get; set; } public virtual DbSet TrialSiteEquipmentSurvey { get; set; } public virtual DbSet TrialSiteSurvey { get; set; } public virtual DbSet StudyStatusDetails { get; set; } #endregion #region Financial public virtual DbSet ReviewerPayInformation { get; set; } public virtual DbSet RankPrice { get; set; } public virtual DbSet TrialPaymentPrice { get; set; } public virtual DbSet AwardPrice { get; set; } public virtual DbSet Payment { get; set; } public virtual DbSet PaymentDetail { get; set; } public virtual DbSet ExchangeRate { get; set; } public virtual DbSet TrialRevenuesPrice { get; set; } public virtual DbSet PaymentAdjustment { get; set; } public virtual DbSet TrialRevenuesPriceVerification { get; set; } #endregion #region QC public virtual DbSet TrialQCQuestionConfigure { get; set; } public virtual DbSet QCQuestionConfigure { get; set; } public virtual DbSet TrialQCQuestionAnswer { get; set; } public virtual DbSet CheckChallengeDialog { get; set; } #endregion #region QA public virtual DbSet QCChallengeDialog { get; set; } //public virtual DbSet QATemplateDictionary { get; set; } public virtual DbSet QCChallenge { get; set; } public virtual DbSet SubjectVisit { get; set; } #endregion #region 工作量分配 public virtual DbSet WorkloadTPs { get; set; } public virtual DbSet WorkloadGlobals { get; set; } public virtual DbSet WorkloadADs { get; set; } public virtual DbSet WorkloadDetails { get; set; } #endregion #region Document public virtual DbSet SystemDocument { get; set; } public virtual DbSet TrialDocument { get; set; } public virtual DbSet TrialDocUserTypeConfirm { get; set; } public virtual DbSet SystemDocConfirmedUser { get; set; } public virtual DbSet SystemDocNeedConfirmedUserType { get; set; } public virtual DbSet TrialDocNeedConfirmedUserType { get; set; } public virtual DbSet TrialDocUserTypeConfirmUser { get; set; } #endregion #region 暂时未用 public virtual DbSet SysMessages { get; set; } public virtual DbSet TrialAttachment { get; set; } public virtual DbSet SystemLogs { get; set; } public virtual DbSet TU { get; set; } public virtual DbSet TR { get; set; } public virtual DbSet RS { get; set; } public virtual DbSet Reports { get; set; } public virtual DbSet StudyReviewer { get; set; } public virtual DbSet KeyInstances { get; set; } public virtual DbSet GlobalRS { get; set; } public virtual DbSet GlobalResult { get; set; } public virtual DbSet ImageLabels { get; set; } //public virtual DbSet QaTemplateItem { get; set; } //public virtual DbSet QaTemplateItemDictionary { get; set; } //public virtual DbSet QaTemplateTemplateItem { get; set; } //public virtual DbSet QATrailTemplate { get; set; } //public virtual DbSet QATrialTemplateItem { get; set; } //public virtual DbSet QARecordTrialTemplateItem { get; set; } //public virtual DbSet QARecordTemplateItemDetail { get; set; } //public virtual DbSet QATemplate { get; set; } //public virtual DbSet QANoticeUser { get; set; } //public virtual DbSet QANotice { get; set; } #endregion public virtual DbSet EmailNoticeConfig { get; set; } public virtual DbSet SystemBasicData { get; set; } public virtual DbSet TrialSign { get; set; } public virtual DbSet TrialStateChange { get; set; } public virtual DbSet SystemAnonymization { get; set; } public virtual DbSet TrialExternalUser { get; set; } public virtual DbSet UserTypeGroup { get; set; } public virtual DbSet DataInspection { get; set; } public virtual DbSet TrialUserPreparation { get; set; } public virtual DbSet FrontAuditConfig { get; set; } public virtual DbSet ConsistencyCheckFile { get; set; } public virtual DbSet CommonDocument { get; set; } public virtual DbSet SystemNotice { get; set; } public virtual DbSet SystemNoticeUserRead { get; set; } public virtual DbSet SystemNoticeUserType { get; set; } #region 废弃 public override int SaveChanges() { //UpdateAuditInfo().GetAwaiter(); AddAudit().GetAwaiter(); return base.SaveChanges(); } public override async Task SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()) { //await UpdateAuditInfo(); await AddAudit(); return await base.SaveChangesAsync(cancellationToken); } public async Task AddAudit() { try { var entities = ChangeTracker.Entries().Where(u => (u.State == EntityState.Modified || u.State == EntityState.Deleted || u.State == EntityState.Added)).Where(x => x.Entity.GetType() != typeof(DataInspection)).ToList(); AuditingData auditingData = new AuditingData(this, _userInfo); await auditingData.IncomingEntitys(entities); } catch (Exception) { } } /// /// 重写savechange方式 统一增加审计信息 CreateUserId CreateTime UpdateTime UpdateUserId 可用事件绑定的方式UpdateAuitUser /// //private async Task UpdateAuditInfo() //{ //ChangeTracker.DetectChanges(); // Important! //// 获取所有更改,删除,新增的实体,但排除审计实体(避免死循环) //var entities = ChangeTracker.Entries() // .Where(u => (u.State == EntityState.Modified || u.State == EntityState.Deleted || u.State == EntityState.Added)).Where(x=>x.Entity.GetType()!=typeof(data)).ToList(); //AuditingData auditingData = new AuditingData(this, _userInfo); //await auditingData.IncomingEntitys(entities); //var items = entities.SelectMany(x => x.Entity.GetType().ToString()); //foreach (var t in entities) //{ // switch (t.State) // { // case EntityState.Deleted: // break; // case EntityState.Modified: // if (t.Entity is IAuditUpdate updateEntity1) // { // updateEntity1.UpdateTime = DateTime.UtcNow.AddHours(8); // updateEntity1.UpdateUserId = _userInfo.Id; // } // break; // //添加的时候,更新审计字段也赋值 // case EntityState.Added: // ////// 仓储添加时 就有id了 // //if (t.Entity is Entity entity && entity.Id == Guid.Empty) // //{ // // entity.Id = NewId.NextGuid(); // //} // if (t.Entity is IAuditAdd addEntity) // { // if (addEntity.CreateTime == default(DateTime)) // { // addEntity.CreateTime = DateTime.UtcNow.AddHours(8); // } // addEntity.CreateUserId = _userInfo.Id; // } // if (t.Entity is IAuditUpdate updateEntity) // { // updateEntity.UpdateTime = DateTime.UtcNow.AddHours(8); // updateEntity.UpdateUserId = _userInfo.Id; // } // if (t.Entity is IAuditAddWithUserName addEntity3) // { // addEntity3.CreateTime = DateTime.UtcNow.AddHours(8); // addEntity3.CreateUserId = _userInfo.Id; // addEntity3.CreateUser = _userInfo.RealName; // } // break; // } //} //} /// /// 事件绑定的方式 更新审计信息 废弃 /// /// /// private void UpdateAuitUser(object sender, EntityEntryEventArgs e) { if (e.Entry.Entity is IAuditUpdate updateEntity) { switch (e.Entry.State) { //case EntityState.Deleted: // entityWithTimestamps.UpdateTime = DateTime.UtcNow; // Console.WriteLine($"Stamped for delete: {e.Entry.Entity}"); // break; case EntityState.Modified: updateEntity.UpdateTime = DateTime.UtcNow; updateEntity.UpdateUserId = _userInfo.Id; break; //添加的时候,更新审计字段也赋值 case EntityState.Added: updateEntity.UpdateTime = DateTime.UtcNow; updateEntity.UpdateUserId = _userInfo.Id; break; } } if (e.Entry.Entity is IAuditAdd addEntity) { switch (e.Entry.State) { case EntityState.Added: addEntity.CreateTime = DateTime.UtcNow; addEntity.CreateUserId = _userInfo.Id; break; } } if (e.Entry.Entity is IAuditAddWithUserName addEntity2) { switch (e.Entry.State) { case EntityState.Added: addEntity2.CreateTime = DateTime.UtcNow; addEntity2.CreateUserId = _userInfo.Id; addEntity2.CreateUser = _userInfo.RealName; break; case EntityState.Deleted: addEntity2.CreateTime = DateTime.UtcNow; addEntity2.CreateUserId = _userInfo.Id; addEntity2.CreateUser = _userInfo.RealName; break; } } } #endregion public virtual DbSet TaskAllocationRule { get; set; } public virtual DbSet VisitTask { get; set; } public virtual DbSet SubjectUser { get; set; } } public class MySequentialGuidValueGenerator : ValueGenerator { public override Guid Next(EntityEntry entry) { return NewId.NextGuid(); } public override bool GeneratesTemporaryValues => false; } }