diff --git a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs index 7fed6537b..dc9d2c138 100644 --- a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs +++ b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs @@ -93,16 +93,21 @@ namespace IRaCIS.Core.Application.Services } - var subject = (await _subjectRepository.FirstOrDefaultAsync(t => t.Id == svCommand.SubjectId)).IfNullThrowException(); //更新受试者 首次给药日期 是否入组确认 if (svCommand.SubjectFirstGiveMedicineTime != null && svCommand.IsBaseLine) { + + //await _subjectRepository.UpdatePartialSearchFirstAsync(svCommand.SubjectId, + // u => new Subject() { FirstGiveMedicineTime = svCommand.SubjectFirstGiveMedicineTime }); + + + + var subject = (await _subjectRepository.FirstOrDefaultAsync(t => t.Id == svCommand.SubjectId)).IfNullThrowException(); + // 更新受试者 subject.FirstGiveMedicineTime = svCommand.SubjectFirstGiveMedicineTime; - - List datas = new List(); datas.Add(new DataInspection() diff --git a/IRaCIS.Core.Application/TestService.cs b/IRaCIS.Core.Application/TestService.cs index e2e6ca3ae..b2c85669a 100644 --- a/IRaCIS.Core.Application/TestService.cs +++ b/IRaCIS.Core.Application/TestService.cs @@ -13,7 +13,7 @@ namespace IRaCIS.Application.Services private readonly IRepository _dicRepository; private readonly IRepository _trialRepository; - public TestService(IRepository dicRepository,IRepository trialRepository) + public TestService(IRepository dicRepository, IRepository trialRepository) { _dicRepository = dicRepository; _trialRepository = trialRepository; @@ -23,9 +23,12 @@ namespace IRaCIS.Application.Services public string Get(testModel testModel) { - var d = _repository.Where(t => t.FullName.Contains("cc")).Select(t => t.FullName).FirstOrDefault(); - var c = _dicRepository.Where(t => t.ParentId != null).Select(t => t.MappedValue).First(); - CultureInfo culture = CultureInfo.CurrentUICulture; + var tt= _dicRepository.UpdatePartialSearchFirstAsync(Guid.Parse("e2b97a6c-35a6-4aa3-7f27-08da13ab33ff"), t => new Dictionary() { Description = "xxxxx" }, true).Result; + + + //var d = _repository.Where(t => t.FullName.Contains("cc")).Select(t => t.FullName).FirstOrDefault(); + //var c = _dicRepository.Where(t => t.ParentId != null).Select(t => t.MappedValue).First(); + //CultureInfo culture = CultureInfo.CurrentUICulture; //var dd = _dicRepository.UpdatePartialFields(Guid.Parse("8a90c96e-0776-4f7b-82a6-18933d339584"), // u => new Dictionary() { ParentId = null, Code = "test" }, true); diff --git a/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs b/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs index c4f700149..07f5d8385 100644 --- a/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs +++ b/IRaCIS.Core.Infra.EFCore/Repository/ICommandRepository.cs @@ -37,6 +37,13 @@ namespace IRaCIS.Core.Infra.EFCore /// 批量删除,EF跟踪方式(所有查询出来,再删除 浪费性能,但是稽查 或者触发某些操作时,需要知道数据库实体信息 不可避免用这种) Task> TrackingBatchDeleteAsync(Expression> deleteFilter); + Task UpdatePartialAsync(TEntity entity, Expression> updateFactory, + bool autoSave = false, CancellationToken cancellationToken = default); + + Task UpdatePartialSearchFirstAsync(Guid id, Expression> updateFactory, + bool autoSave = false, CancellationToken cancellationToken = default); + + } public interface ICommandRepository where TEntity : class diff --git a/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs b/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs index 604a27083..c363c3aa3 100644 --- a/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs +++ b/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs @@ -44,7 +44,7 @@ namespace IRaCIS.Core.Infra.EFCore #region 异步 EF 跟踪 添加 - public async Task> AddRangeAsync(IEnumerable entities,bool isSaveAudit=false) + public async Task> AddRangeAsync(IEnumerable entities, bool isSaveAudit = false) { foreach (var addEntity in entities) { @@ -55,7 +55,7 @@ namespace IRaCIS.Core.Infra.EFCore } /// EF跟踪方式 添加 - public async ValueTask AddAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default,bool isSaveAudit=false) + public async ValueTask AddAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default, bool isSaveAudit = false) { await _dbSet.AddAsync(entity).ConfigureAwait(false); @@ -79,7 +79,7 @@ namespace IRaCIS.Core.Infra.EFCore await EntityVerifyAsync(true, verify); - entity = await AddAsync(entity,autoSave); + entity = await AddAsync(entity, autoSave); return entity; @@ -207,7 +207,7 @@ namespace IRaCIS.Core.Infra.EFCore #region 异步 EF 跟踪 自动生成 更新 和删除语句 - /// EF跟踪方式 更新,全字段更新 + /// EF跟踪方式 更新,全字段更新 不好 public async Task UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) { _dbSet.Update(entity); @@ -223,7 +223,71 @@ namespace IRaCIS.Core.Infra.EFCore } - + /// EF跟踪方式 先查询出来,再更新部分字段 稽查的时候需要完整的实体信息 + public async Task UpdatePartialAsync(TEntity entity, Expression> updateFactory, bool autoSave = false, CancellationToken cancellationToken = default) + { + var entityEntry = _dbContext.Entry(entity); + + + entityEntry.State = EntityState.Detached; + + + List list = ((MemberInitExpression)updateFactory.Body).Bindings.Select(mb => mb.Member.Name) + .Select(propName => typeof(TEntity).GetProperty(propName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)).ToList(); + + Func func = updateFactory.Compile(); + + TEntity applyObj = func(entity); + + foreach (PropertyInfo prop in list) + { + object value = prop.GetValue((object)applyObj); + prop.SetValue((object)entity, value); + + _dbContext.Entry(entity).Property(prop.Name).IsModified = true; + } + + return await SaveChangesAsync(cancellationToken); + + + } + + /// EF跟踪方式 先查询出来,再更新部分字段 稽查的时候需要完整的实体信息 + public async Task UpdatePartialSearchFirstAsync(Guid id, Expression> updateFactory, + bool autoSave = false, CancellationToken cancellationToken = default) + { + var searchEntity = await _dbSet.AsNoTracking().FirstOrDefaultAsync(t => t.Id == id); + + if (searchEntity == null) + { + throw new BusinessValidationFailedException( + " Update object not exist in db,Please check if the parameter Id is passed incorrectly"); + } + + + List list = ((MemberInitExpression)updateFactory.Body).Bindings.Select(mb => mb.Member.Name) + .Select(propName => typeof(TEntity).GetProperty(propName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)).ToList(); + + Func func = updateFactory.Compile(); + + TEntity applyObj = func(searchEntity); + + foreach (PropertyInfo prop in list) + { + object value = prop.GetValue((object)applyObj); + prop.SetValue((object)searchEntity, value); + + _dbContext.Entry(searchEntity).Property(prop.Name).IsModified = true; + } + + + + await SaveChangesAsync(cancellationToken); + + return searchEntity; + } + + /// EF跟踪方式 删除 public async Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) @@ -524,12 +588,12 @@ namespace IRaCIS.Core.Infra.EFCore JsonData[item.Key] = string.Join(',', await _dbContext.Dictionary.Where(x => x.Code == item.Code).GroupJoin( _dbContext.Dictionary.Where(x => guids.Contains(x.ChildGroup)), a => a.Id, b => b.ParentId, (a, b) => new - { - parent = b - }).SelectMany(a => a.parent, (m, n) => new - { - value = n.ValueCN - }).Select(x => x.value).ToListAsync() + { + parent = b + }).SelectMany(a => a.parent, (m, n) => new + { + value = n.ValueCN + }).Select(x => x.value).ToListAsync() ); } else @@ -590,7 +654,7 @@ namespace IRaCIS.Core.Infra.EFCore } - private async Task AddInspectionAsync(TEntity entity,bool isSaveAudit=false) + private async Task AddInspectionAsync(TEntity entity, bool isSaveAudit = false) { List datas = new List();