452 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			452 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C#
		
	
	
| 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 IRaCIS.Core.Domain.Share;
 | |
| using Microsoft.EntityFrameworkCore.Infrastructure;
 | |
| using UserTypeGroup = IRaCIS.Core.Domain.Models.UserTypeGroup;
 | |
| 
 | |
| namespace IRaCIS.Core.Infra.EFCore
 | |
| {
 | |
|     public class IRaCISDBContext : DbContext
 | |
|     {
 | |
|         public  readonly IUserInfo _userInfo;
 | |
| 
 | |
|         // 在控制台
 | |
|         //public static readonly ILoggerFactory MyLoggerFactory    = LoggerFactory.Create(builder => { builder.AddConsole(); });
 | |
|         // 调试窗口
 | |
|         public static readonly ILoggerFactory MyLoggerFactory = LoggerFactory.Create(builder => { builder.AddDebug(); });
 | |
| 
 | |
|         public IRaCISDBContext(DbContextOptions<IRaCISDBContext> options, IUserInfo userInfo) : base(options)
 | |
|         {
 | |
|             _userInfo = userInfo;
 | |
|             //_configuration = configuration;
 | |
|         }
 | |
| 
 | |
|          
 | |
|         //比数据库上下文构造函数先执行 不能构造函数注入的方式使用配置文件
 | |
|         protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
 | |
|         {
 | |
|             optionsBuilder.UseLoggerFactory(MyLoggerFactory)
 | |
|                 .ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactoryDesignTimeSupport>();
 | |
| 
 | |
|             //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 DynamicModelCacheKeyFactory : IModelCacheKeyFactory
 | |
|         //{
 | |
|         //    public object Create(DbContext context)
 | |
|         //        => context is IRaCISDBContext dynamicContext
 | |
|         //            ? (context.GetType(), dynamicContext._userInfo.IsEn_Us)
 | |
|         //            : (object)context.GetType();
 | |
|         //}
 | |
| 
 | |
|         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<TrialSiteSurvey>().HasMany(s => s.TrialSiteUserSurveyList).WithOne(sv => sv.TrialSiteSurvey);
 | |
|             //modelBuilder.Entity<TrialSiteSurvey>().HasMany(s => s.TrialSiteEquipmentSurveyList).WithOne(sv => sv.TrialSiteSurvey);
 | |
|             //modelBuilder.Entity<Dictionary>().Ignore(t => t.MappedValue);
 | |
|             //modelBuilder.Entity<Dictionary>().Property(t => t.MappedValue).HasComputedColumnSql(_userInfo.IsEn_Us? "[Value]":"[ValueCN]");
 | |
|             //modelBuilder.Entity<TrialSiteSurvey>()//  .HasQueryFilter(t => t.IsDeleted == false);
 | |
| 
 | |
| 
 | |
|             if (_userInfo.IsEn_Us)
 | |
|             {
 | |
|                 modelBuilder.Entity<Dictionary>().Property(t => t.MappedValue).HasColumnName( "Value" );
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 modelBuilder.Entity<Dictionary>().Property(t => t.MappedValue).HasColumnName( "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);
 | |
| 
 | |
| 
 | |
| 
 | |
|             //modelBuilder.Entity<Dictionary>().Property(t => t.MappedValue).HasColumnName(_userInfo.IsEn_Us ? "Value" : "ValueCN").UsePropertyAccessMode(PropertyAccessMode.Property);
 | |
| 
 | |
| 
 | |
| 
 | |
|             // 软删除配置
 | |
|             foreach (var entityType in modelBuilder.Model.GetEntityTypes())
 | |
|             {
 | |
|                 if (typeof(ISoftDelete).IsAssignableFrom(entityType.ClrType))
 | |
|                 {
 | |
|                     entityType.AddSoftDeleteQueryFilter();
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|         }
 | |
| 
 | |
|         #region Doctor
 | |
|         public virtual DbSet<Dictionary> Dictionary { get; set; }
 | |
|         public virtual DbSet<Doctor> Doctor { get; set; }
 | |
|         public virtual DbSet<DoctorDictionary> DoctorDictionary { get; set; }
 | |
|         public virtual DbSet<Postgraduate> Postgraduate { get; set; }
 | |
|         public virtual DbSet<Education> Education { get; set; }
 | |
|         public virtual DbSet<ResearchPublication> ResearchPublications { get; set; }
 | |
|         public virtual DbSet<TrialExperience> TrialExperience { get; set; }
 | |
| 
 | |
|         public virtual DbSet<UserDoctor> UserDoctor { get; set; }
 | |
|         public virtual DbSet<Vacation> Vacation { get; set; }
 | |
| 
 | |
|         public virtual DbSet<Attachment> Attachment { get; set; }
 | |
|         public virtual DbSet<TrialExperienceCriteria> TrialExperienceCriteria { get; set; }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Enroll
 | |
| 
 | |
|         public virtual DbSet<Workload> DoctorWorkload { get; set; }
 | |
|         public virtual DbSet<Enroll> IntoGroup { get; set; }
 | |
|         public virtual DbSet<EnrollDetail> EnrollDetails { get; set; }
 | |
| 
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Subject and Visit and study
 | |
|         public virtual DbSet<StudyMonitor> StudyMonitor { get; set; }
 | |
| 
 | |
|         public virtual DbSet<Subject> Subjects { get; set; }
 | |
|         public virtual DbSet<VisitStage> VisitPlans { get; set; }
 | |
|         public virtual DbSet<VisitPlanInfluenceStudy> VisitPlanInfluenceStudy { get; set; }
 | |
| 
 | |
|         public virtual DbSet<VisitPlanInfluenceStat> VisitPlanInfluenceStat { get; set; }
 | |
| 
 | |
|         public virtual DbSet<NoneDicomStudyFile> NoneDicomStudyFile { get; set; }
 | |
|         public virtual DbSet<NoneDicomStudy> NoneDicomStudy { get; set; }
 | |
|         public virtual DbSet<PreviousPDF> PreviousPDF { get; set; }
 | |
|         public virtual DbSet<PreviousSurgery> PreviousSurgery { get; set; }
 | |
|         public virtual DbSet<PreviousOther> PreviousOther { get; set; }
 | |
|         public virtual DbSet<PreviousHistory> PreviousHistory { get; set; }
 | |
| 
 | |
|         public virtual DbSet<StudyDTF> StudyDTF { get; set; }
 | |
|         public virtual DbSet<DicomStudy> DicomStudys { get; set; }
 | |
|         public virtual DbSet<DicomSeries> DicomSeries { get; set; }
 | |
|         public virtual DbSet<DicomInstance> DicomInstances { get; set; }
 | |
|         public virtual DbSet<ImageShare> ImageShare { get; set; }
 | |
| 
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Management
 | |
|         public virtual DbSet<VerificationCode> VerificationCodes { get; set; }
 | |
|         public virtual DbSet<Menu> MenuFunctions { get; set; }
 | |
|         public virtual DbSet<Role> Roles { get; set; }
 | |
|         public virtual DbSet<UserTypeMenu> UserTypeMenuFunction { get; set; }
 | |
|         public virtual DbSet<User> Users { get; set; }
 | |
|         public virtual DbSet<UserRole> UserRoles { get; set; }
 | |
|         public virtual DbSet<TrialAudit> TrialAudit { get; set; }
 | |
|         public virtual DbSet<UserType> UserType { get; set; }
 | |
| 
 | |
|         public virtual DbSet<SaveChangesAudit> SaveChangesAudits { get; set; }
 | |
| 
 | |
| 
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Institution
 | |
| 
 | |
| 
 | |
| 
 | |
|         public virtual DbSet<Site> ResearchCenter { get; set; }
 | |
|         public virtual DbSet<Hospital> Hospitals { get; set; }
 | |
|         public virtual DbSet<CRO> CROCompany { get; set; }
 | |
|         public virtual DbSet<Sponsor> Sponsor { get; set; }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Trial
 | |
|         public virtual DbSet<Trial> Trial { get; set; }
 | |
|         public virtual DbSet<TrialStatusDetail> TrialDetail { get; set; }
 | |
|         public virtual DbSet<TrialUser> UserTrial { get; set; }
 | |
| 
 | |
|         public virtual DbSet<TrialDictionary> ProjectDictionary { get; set; }
 | |
| 
 | |
|         public virtual DbSet<TrialSiteUser> UserTrialSite { get; set; }
 | |
|         public virtual DbSet<TrialSite> TrialSite { get; set; }
 | |
| 
 | |
|         public virtual DbSet<TrialSiteUserSurvey> TrialSiteUserSurvey { get; set; }
 | |
|         public virtual DbSet<TrialSiteEquipmentSurvey> TrialSiteEquipmentSurvey { get; set; }
 | |
|         public virtual DbSet<TrialSiteSurvey> TrialSiteSurvey { get; set; }
 | |
| 
 | |
|         public virtual DbSet<StudyStatusDetail> StudyStatusDetails { get; set; }
 | |
| 
 | |
| 
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Financial
 | |
|         public virtual DbSet<ReviewerPayInformation> ReviewerPayInformation { get; set; }
 | |
|         public virtual DbSet<RankPrice> RankPrice { get; set; }
 | |
|         public virtual DbSet<TrialPaymentPrice> TrialPaymentPrice { get; set; }
 | |
|         public virtual DbSet<VolumeReward> AwardPrice { get; set; }
 | |
|         public virtual DbSet<Payment> Payment { get; set; }
 | |
|         public virtual DbSet<PaymentDetail> PaymentDetail { get; set; }
 | |
|         public virtual DbSet<ExchangeRate> ExchangeRate { get; set; }
 | |
|         public virtual DbSet<TrialRevenuesPrice> TrialRevenuesPrice { get; set; }
 | |
|         public virtual DbSet<PaymentAdjustment> PaymentAdjustment { get; set; }
 | |
|         public virtual DbSet<TrialRevenuesPriceVerification> TrialRevenuesPriceVerification { get; set; }
 | |
| 
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region QC
 | |
| 
 | |
|         public virtual DbSet<TrialQCQuestion> TrialQCQuestionConfigure { get; set; }
 | |
|         public virtual DbSet<QCQuestion> QCQuestionConfigure { get; set; }
 | |
|         public virtual DbSet<TrialQCQuestionAnswer> TrialQCQuestionRecord { get; set; }
 | |
|         public virtual DbSet<CheckChallengeDialog> CheckChallengeDialog { get; set; }
 | |
|         #endregion
 | |
| 
 | |
| 
 | |
|         #region QA
 | |
|        
 | |
|         public virtual DbSet<QCChallengeDialog> QCChallengeDialog { get; set; }
 | |
|         public virtual DbSet<QANotice> QATemplateDictionary { get; set; }
 | |
|         public virtual DbSet<QCChallenge> QCChallenge { get; set; }
 | |
|         public virtual DbSet<SubjectVisit> SubjectVisit { get; set; }
 | |
|         #endregion
 | |
| 
 | |
|         #region 工作量分配
 | |
|         public virtual DbSet<WorkloadTP> WorkloadTPs { get; set; }
 | |
|         public virtual DbSet<WorkloadGlobal> WorkloadGlobals { get; set; }
 | |
|         public virtual DbSet<WorkloadAD> WorkloadADs { get; set; }
 | |
|         public virtual DbSet<WorkloadDetail> WorkloadDetails { get; set; }
 | |
|         #endregion
 | |
| 
 | |
| 
 | |
|         #region Document
 | |
|         public virtual DbSet<SystemDocument> SystemDocument { get; set; }
 | |
|         public virtual DbSet<TrialDocument> TrialDocument { get; set; }
 | |
|         public virtual DbSet<TrialDocNeedConfirmedUserType> TrialDocUserTypeConfirm { get; set; }
 | |
|         public virtual DbSet<SystemDocConfirmedUser> SystemDocConfirmedUser { get; set; }
 | |
|         public virtual DbSet<SystemDocNeedConfirmedUserType> SystemDocNeedConfirmedUserType { get; set; }
 | |
| 
 | |
|         public virtual DbSet<TrialDocUserTypeConfirmedUser> TrialDocUserTypeConfirmUser { get; set; }
 | |
|         #endregion
 | |
| 
 | |
|         #region 暂时未用
 | |
|         public virtual DbSet<Message> SysMessages { get; set; }
 | |
|         public virtual DbSet<TrialAttachment> TrialAttachment { get; set; }
 | |
|         public virtual DbSet<SystemLog> SystemLogs { get; set; }
 | |
|         public virtual DbSet<TU> TU { get; set; }
 | |
|         public virtual DbSet<TR> TR { get; set; }
 | |
|         public virtual DbSet<RS> RS { get; set; }
 | |
|         public virtual DbSet<Report> Reports { get; set; }
 | |
|         public virtual DbSet<StudyReviewer> StudyReviewer { get; set; }
 | |
| 
 | |
|         public virtual DbSet<KeyInstance> KeyInstances { get; set; }
 | |
|         public virtual DbSet<GlobalRS> GlobalRS { get; set; }
 | |
|         public virtual DbSet<GlobalResult> GlobalResult { get; set; }
 | |
|         public virtual DbSet<ImageLabel> ImageLabels { get; set; }
 | |
|         //public virtual DbSet<QATemplateItem> QaTemplateItem { get; set; }
 | |
|         //public virtual DbSet<QATemplateItemDictionary> QaTemplateItemDictionary { get; set; }
 | |
|         //public virtual DbSet<QATemplateTemplateItem> QaTemplateTemplateItem { get; set; }
 | |
|         //public virtual DbSet<QATrialTemplate> QATrailTemplate { get; set; }
 | |
|         //public virtual DbSet<QATrialTemplateItem> QATrialTemplateItem { get; set; }
 | |
|         //public virtual DbSet<QAAboutTrialTemplateItem> QARecordTrialTemplateItem { get; set; }
 | |
|         //public virtual DbSet<QARecordTemplateItemDetail> QARecordTemplateItemDetail { get; set; }
 | |
|         //public virtual DbSet<QATemplate> QATemplate { get; set; }
 | |
|         public virtual DbSet<QANoticeUser> QANoticeUser { get; set; }
 | |
|         public virtual DbSet<QANotice> QANotice { get; set; }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         public virtual DbSet<EmailNoticeConfig> EmailNoticeConfig { get; set; }
 | |
|         public virtual DbSet<SystemBasicData> SystemBasicData { get; set; }
 | |
| 
 | |
|         public virtual DbSet<TrialSign> TrialSign { get; set; }
 | |
| 
 | |
|         public virtual DbSet<TrialStateChange> TrialStateChange { get; set; }
 | |
| 
 | |
|         public virtual DbSet<SystemAnonymization> SystemAnonymization { get; set; }
 | |
| 
 | |
|         public virtual DbSet<TrialExternalUser> TrialExternalUser { get; set; }
 | |
| 
 | |
|         public virtual DbSet<UserTypeGroup> UserTypeGroup { get; set; }
 | |
| 
 | |
|         public virtual DbSet<DataInspection> DataInspection { get; set; }
 | |
| 
 | |
|         public virtual DbSet<TrialUserPreparation> TrialUserPreparation { get; set; }
 | |
| 
 | |
| 
 | |
|         public virtual DbSet<FrontAuditConfig> FrontAuditConfig { get; set; }
 | |
| 
 | |
|         public virtual DbSet<CommonDocument> CommonDocument { get; set; }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         public override int SaveChanges()
 | |
|         {
 | |
|             UpdateAuditInfo();
 | |
|             return base.SaveChanges();
 | |
|         }
 | |
| 
 | |
|         public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
 | |
|         {
 | |
|             UpdateAuditInfo();
 | |
|             return base.SaveChangesAsync(cancellationToken);
 | |
|         }
 | |
| 
 | |
|         #region 重写savechange方式 统一增加审计信息 CreateUserId CreateTime UpdateTime UpdateUserId  可用事件绑定的方式UpdateAuitUser
 | |
|         private void UpdateAuditInfo()
 | |
|         {
 | |
|           
 | |
|             ChangeTracker.DetectChanges(); // Important!
 | |
| 
 | |
|             //// 获取所有更改,删除,新增的实体,但排除审计实体(避免死循环)
 | |
|             var entities = ChangeTracker.Entries()
 | |
|                 .Where(u => (u.State == EntityState.Modified || u.State == EntityState.Deleted || u.State == EntityState.Added));
 | |
| 
 | |
|             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;
 | |
|                         }
 | |
| 
 | |
|                         if(t.Entity is ISoftDelete updateEntity2)
 | |
|                         {
 | |
|                             if (updateEntity2.IsDeleted == true)
 | |
|                             {
 | |
|                                 updateEntity2.DeletedTime = DateTime.UtcNow.AddHours(8);
 | |
|                             }
 | |
|                         }
 | |
| 
 | |
|                         break;
 | |
|                     //添加的时候,更新审计字段也赋值
 | |
|                     case EntityState.Added:
 | |
|                         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;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
| 
 | |
|            
 | |
|         }
 | |
|         #endregion
 | |
| 
 | |
|         #region 事件绑定的方式 更新审计信息
 | |
| 
 | |
|         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
 | |
| 
 | |
|     }
 | |
| } |