From f37783c91ad9d56c9f1cdf7d4bd88ad3c55b31ad Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Fri, 22 Apr 2022 11:14:02 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BB=93=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repository/Repository.cs | 832 +++++++++--------- 1 file changed, 419 insertions(+), 413 deletions(-) diff --git a/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs b/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs index 49514d9be..75a4f22ee 100644 --- a/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs +++ b/IRaCIS.Core.Infra.EFCore/Repository/Repository.cs @@ -40,67 +40,9 @@ namespace IRaCIS.Core.Infra.EFCore } - #region 异步部分 - - /// EF跟踪方式 添加 - public async ValueTask AddAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) - { - - await _dbSet.AddAsync(entity).ConfigureAwait(false); - - await AddInspectionAsync(entity); - - if (autoSave) - { - await SaveChangesAsync(cancellationToken); - } - - return entity; - } - private async Task AddInspectionAsync(TEntity entity) - { - List datas = new List(); - - var createtime = DateTime.Now.AddSeconds(1); - - // 受试者 - if (typeof(TEntity) == typeof(Subject)) - { - Subject data = entity as Subject; - datas.Add(new DataInspection() - { - TrialId = data.TrialId, - SiteId = data.SiteId, - SubjectId = data.Id, - SubjectCode = data.Code, - IsSign = false, - CreateTime = createtime, - Identification = "Init|Subject|Status|Subject", - JsonDetail = JsonConvert.SerializeObject(new - { - Status = "新增", - }) - }); - } - await AddListInspectionRecordAsync(datas); - } - - public async Task InsertOrUpdateAsync(TFrom from, bool autoSave = false, params EntityVerifyExp[] verify) - { - var entity = _mapper.Map(from); - - - if (entity.Id == Guid.Empty) - { - return await InsertFromDTOAsync(from, autoSave, verify); - } - else - { - return await UpdateFromDTOAsync(from, autoSave, false, verify); - } - } + #region 异步添加 private async Task EntityVerifyAsync(bool isAdd, EntityVerifyExp[] verify, Guid? entitydId = null) @@ -139,6 +81,36 @@ namespace IRaCIS.Core.Infra.EFCore } + + + public async Task> AddRangeAsync(IEnumerable entities) + { + foreach (var addEntity in entities) + { + await AddAsync(addEntity); + } + + return entities; + } + + /// EF跟踪方式 添加 + public async ValueTask AddAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) + { + + await _dbSet.AddAsync(entity).ConfigureAwait(false); + + await AddInspectionAsync(entity); + + if (autoSave) + { + await SaveChangesAsync(cancellationToken); + } + + return entity; + } + + + public async Task InsertFromDTOAsync(TFrom from, bool autoSave = false, params EntityVerifyExp[] verify) { var entity = _mapper.Map(from); @@ -146,17 +118,382 @@ namespace IRaCIS.Core.Infra.EFCore await EntityVerifyAsync(true, verify); - entity= await AddAsync(entity); + entity = await AddAsync(entity); return entity; } + #endregion + #region 异步更新 + + + /// 用前端传递的视图模型字段,更新,同时返回数据库该条记录的原始信息,方便对比某些字段是否更改,进行相应的逻辑操作 + + public async Task UpdateFromDTOAsync(TFrom from, bool autoSave = false, bool ignoreDtoNullProperty = true, params EntityVerifyExp[] verify) + { + + var entity = _mapper.Map(from); + + await EntityVerifyAsync(false, verify, entity.Id); + + var dbEntity = await _dbSet.IgnoreQueryFilters().FirstOrDefaultAsync(t => t.Id == entity.Id).ConfigureAwait(false); + + if (dbEntity == null) + { + throw new BusinessValidationFailedException( + " Update object not exist in db,Please check if the parameter Id is passed incorrectly"); + } + + var dbBeforEntity = dbEntity.Clone(); + + + _mapper.Map(from, dbEntity); + + + //DTO null 属性不更新 防止意外操作,导致保存数据错误,或者 add 和update 用一个模型,更新的时候,只传递了部分字段,导致,不想更新的字段,因为没传递值,用null覆盖了 + // Guid?属性 为null 时 映射到 Guid 时 默认会变成 Guid.Empty + if (ignoreDtoNullProperty) + { + var dbEntityProp = typeof(TEntity).GetProperties(); + foreach (var propertyInfo in from.GetType().GetProperties()) + { + if (propertyInfo.GetValue(from) == null && dbEntityProp.Any(t => t.Name == propertyInfo.Name)) + { + _dbContext.Entry(dbEntity).Property(propertyInfo.Name).IsModified = false; + } + } + } + + await SaveChangesAsync(autoSave); + + + return dbBeforEntity; + } + + + + /// EF跟踪方式 生成 部分字段更新, 通过主键id 和表达式树 更新部分字段 + /// 例如 Guid.Parse("8a90c96e-0776-4f7b-82a6-18933d339584"),u => new Dictionary() { ParentId = null, Code = "test" }默认会去处理更新更新人 更新时间 + + public async Task UpdatePartialFieldsAsync(Guid id, Expression> updateFactory, bool autoSave = false, params EntityVerifyExp[] verify) + { + await SetPartialFieldUpdateAsync(id, updateFactory, verify); + + await SaveChangesAsync(autoSave); + + } + + + /// EF跟踪方式 生成 部分字段立即更新,默认会去处理更新更新人 更新时间 + public async Task UpdatePartialFieldsNowAsync(Guid id, Expression> updateFactory, + params EntityVerifyExp[] verify) + { + await SetPartialFieldUpdateAsync(id, updateFactory, verify); + return await SaveChangesAsync(true); + } + + + /// 注意 模型标注了 ConcurrencyCheck的属性,这样的实体,不适合用部分字段更新,ef生成的更新sql会自动带上ConcurrencyCheck的属性条件 + private async Task SetPartialFieldUpdateAsync(Guid id, Expression> updateFactory, params EntityVerifyExp[] verify) + { + await EntityVerifyAsync(false, verify, id); + + var entity = new TEntity() { Id = id }; + + 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; + } + + #region Test + + + //updateFactory.Compile()(entity); + + //List propNameList = ((MemberInitExpression)updateFactory.Body).Bindings.Select(mb => mb.Member.Name).ToList(); + + //foreach (string propName in propNameList) + //{ + // _dbContext.Entry(entity).Property(propName).IsModified = true; + //} + + #endregion + } + + + + + + #endregion + + + #region 异步 单个完整实体 EF 跟踪 自动生成 更新 和删除语句 + + + /// EF跟踪方式 更新,全字段更新 + public async Task UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) + { + _dbSet.Update(entity); + + if (autoSave) + { + return await SaveChangesAsync(cancellationToken); + } + else + { + return false; + } + } + + + /// EF跟踪方式 删除 + public async Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) + { + _dbSet.Remove(entity); + + if (autoSave) + { + return await SaveChangesAsync(cancellationToken); + } + else + { + return false; + } + } + + #endregion + + #region 异步 批量删除和更新 + + + + /// 批量删除,EF跟踪方式(所有查询出来,再删除 浪费性能,但是稽查 或者触发某些操作时,需要知道数据库实体信息 不可避免用这种) + public async Task TrackingBatchDeleteAsync(Expression> deleteFilter) + { + var waitDeleteList = await _dbSet.IgnoreQueryFilters().Where(deleteFilter).ToListAsync(); + + foreach (var deleteItem in waitDeleteList) + { + await DeleteAsync(deleteItem, false); + } + + } + + + /// 批量删除,相当于原生sql, 没用EF跟踪方式(所有查询出来,再删除 浪费性能) + public async Task BatchDeleteAsync(Expression> deleteFilter) + { + return await _dbSet.IgnoreQueryFilters().Where(deleteFilter).BatchDeleteAsync() > 0; + } + + + /// 批量更新,相当于原生sql, 没用EF跟踪方式(所有查询出来,再更新 浪费性能) + public async Task BatchUpdateAsync(Expression> where, + Expression> updateFactory) + { + + var bindings = ((MemberInitExpression)updateFactory.Body).Bindings.ToList(); + + if (typeof(IAuditUpdate).IsAssignableFrom(typeof(TEntity))) + { + var hasPropNameList = bindings.Select(t => t.Member.Name).ToList(); + + if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateTime))) + { + bindings.Add(Expression.Bind(typeof(TEntity).GetMember(nameof(IAuditUpdate.UpdateTime))[0], Expression.Constant(DateTime.Now))); + + } + + if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateUserId))) + { + bindings.Add(Expression.Bind(typeof(TEntity).GetMember(nameof(IAuditUpdate.UpdateUserId))[0], Expression.Constant(_userInfo.Id))); + + } + } + + + var member = Expression.MemberInit(Expression.New(typeof(TEntity)), bindings); + + var factory = Expression.Lambda>(member, Expression.Parameter(typeof(TEntity), "x")); + + + return await _dbSet.IgnoreQueryFilters().Where(where).BatchUpdateAsync(factory) > 0; + + + + } + + + #endregion + + + #region 保存 和忽略 + + private async Task SaveChangesAsync(bool autoSave) + { + if (autoSave) + { + return await SaveChangesAsync(); + } + else + { + return false; + } + } + + /// + /// 忽略空值属性 + /// + /// + /// + private void IgnoreNullValues(ref TEntity entity, bool? ignoreNullValues = null) + { + var isIgnore = ignoreNullValues; + if (isIgnore == false) return; + + // 获取所有的属性 + var properties = _dbSet.EntityType.GetProperties(); + if (properties == null) return; + + foreach (var propety in properties) + { + var entityProperty = _dbContext.Entry(entity).Property(propety.Name); + var propertyValue = entityProperty?.CurrentValue; + var propertyType = entityProperty?.Metadata?.PropertyInfo?.PropertyType; + + // 判断是否是无效的值,比如为 null,默认时间,以及空 Guid 值 + var isInvalid = propertyValue == null + || (propertyType == typeof(DateTime) && propertyValue?.ToString() == new DateTime().ToString()) + || (propertyType == typeof(DateTimeOffset) && propertyValue?.ToString() == new DateTimeOffset().ToString()) + || (propertyType == typeof(Guid) && propertyValue?.ToString() == Guid.Empty.ToString()); + + if (isInvalid && entityProperty != null) + { + entityProperty.IsModified = false; + } + } + } + + + public async Task SaveChangesAsync(CancellationToken cancellationToken = default) + { + return await _dbContext.SaveChangesAsync(cancellationToken) > 0; + } + + + #endregion + + #region 不常用 + + public async Task InsertOrUpdateAsync(TFrom from, bool autoSave = false, params EntityVerifyExp[] verify) + { + var entity = _mapper.Map(from); + + + if (entity.Id == Guid.Empty) + { + return await InsertFromDTOAsync(from, autoSave, verify); + } + else + { + return await UpdateFromDTOAsync(from, autoSave, false, verify); + } + } + + /// EF跟踪方式 生成 部分字段更新 (只更新传递的字段名 new[] {nameof(User.Name), nameof(User.Age)) + public async Task UpdatePartialFieldsAsync(TEntity entity, string[] propertyNames, + bool autoSave = false, bool ignoreEntityNullProperty = true, params EntityVerifyExp[] verify) + { + await EntityVerifyAsync(false, verify, entity.Id); + + var entityEntry = _dbContext.Entry(entity); + entityEntry.State = EntityState.Detached; + + + foreach (var propertyName in propertyNames) + { + _dbContext.Entry(entity).Property(propertyName).IsModified = true; + } + + // 忽略空值 + IgnoreNullValues(ref entity, ignoreEntityNullProperty); + + return entityEntry.Entity; + } + + /// 更新 排除某些字段的更新 排除方式: new[] {nameof(User.Name), nameof(User.Age) + public async Task UpdateExcludeFields(TEntity entity, string[] propertyNames, bool autoSave = false, bool ignoreEntityNullProperty = true, params EntityVerifyExp[] verify) + { + + await EntityVerifyAsync(false, verify, entity.Id); + + var entityEntry = _dbContext.Entry(entity); + entityEntry.State = EntityState.Modified; + + + foreach (var propertyName in propertyNames) + { + _dbContext.Entry(entity).Property(propertyName).IsModified = false; + } + + // 忽略空值 + IgnoreNullValues(ref entity, ignoreEntityNullProperty); + + return entityEntry.Entity; + } + + + #endregion #region 稽查 + + + private async Task AddInspectionAsync(TEntity entity) + { + List datas = new List(); + + var createtime = DateTime.Now.AddSeconds(1); + + // 受试者 + if (typeof(TEntity) == typeof(Subject)) + { + Subject data = entity as Subject; + datas.Add(new DataInspection() + { + TrialId = data.TrialId, + SiteId = data.SiteId, + SubjectId = data.Id, + SubjectCode = data.Code, + IsSign = false, + CreateTime = createtime, + Identification = "Init|Subject|Status|Subject", + JsonDetail = JsonConvert.SerializeObject(new + { + Status = "新增", + }) + }); + } + await AddListInspectionRecordAsync(datas); + } /// /// 添加稽查记录 /// @@ -388,279 +725,8 @@ namespace IRaCIS.Core.Infra.EFCore } #endregion - /// - /// 用前端传递的视图模型字段,更新,同时返回数据库该条记录的原始信息,方便对比某些字段是否更改,进行相应的逻辑操作 - /// - /// - /// - /// - /// - /// - /// - /// - public async Task UpdateFromDTOAsync(TFrom from, bool autoSave = false, bool ignoreDtoNullProperty = true, params EntityVerifyExp[] verify) - { - - var entity = _mapper.Map(from); - - await EntityVerifyAsync(false, verify, entity.Id); - - var dbEntity = await _dbSet.IgnoreQueryFilters().FirstOrDefaultAsync(t => t.Id == entity.Id).ConfigureAwait(false); - - if (dbEntity == null) - { - throw new BusinessValidationFailedException( - " Update object not exist in db,Please check if the parameter Id is passed incorrectly"); - } - - var dbBeforEntity = dbEntity.Clone(); - - - _mapper.Map(from, dbEntity); - - - //DTO null 属性不更新 防止意外操作,导致保存数据错误,或者 add 和update 用一个模型,更新的时候,只传递了部分字段,导致,不想更新的字段,因为没传递值,用null覆盖了 - // Guid?属性 为null 时 映射到 Guid 时 默认会变成 Guid.Empty - if (ignoreDtoNullProperty) - { - var dbEntityProp = typeof(TEntity).GetProperties(); - foreach (var propertyInfo in from.GetType().GetProperties()) - { - if (propertyInfo.GetValue(from) == null && dbEntityProp.Any(t => t.Name == propertyInfo.Name)) - { - _dbContext.Entry(dbEntity).Property(propertyInfo.Name).IsModified = false; - } - } - } - - await SaveChangesAsync(autoSave); - - - return dbBeforEntity; - } - - - private async Task SaveChangesAsync(bool autoSave) - { - if (autoSave) - { - return await SaveChangesAsync(); - } - else - { - return false; - } - } - - /// - /// 通过主键id 和表达式树 更新部分字段 例如 Guid.Parse("8a90c96e-0776-4f7b-82a6-18933d339584"),u => new Dictionary() { ParentId = null, Code = "test" } 默认会去处理更新更新人 更新时间 - /// - /// - /// - /// - /// - /// - public async Task UpdatePartialFieldsAsync(Guid id, Expression> updateFactory, bool autoSave = false, params EntityVerifyExp[] verify) - { - await SetPartialFieldUpdateAsync(id, updateFactory, verify); - - await SaveChangesAsync(autoSave); - - } - - public async Task UpdatePartialFieldsNowAsync(Guid id, Expression> updateFactory, - params EntityVerifyExp[] verify) - { - await SetPartialFieldUpdateAsync(id, updateFactory, verify); - return await SaveChangesAsync(true); - } - - /// - /// 部分字段更新,注意 模型标注了 ConcurrencyCheck的属性,这样的实体,不适合用部分字段更新,ef生成的更新sql会自动带上ConcurrencyCheck的属性条件 - /// - /// - /// - /// - /// - private async Task SetPartialFieldUpdateAsync(Guid id, Expression> updateFactory, params EntityVerifyExp[] verify) - { - await EntityVerifyAsync(false, verify, id); - - var entity = new TEntity() { Id = id }; - - 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; - } - - #region Test - - - //updateFactory.Compile()(entity); - - //List propNameList = ((MemberInitExpression)updateFactory.Body).Bindings.Select(mb => mb.Member.Name).ToList(); - - //foreach (string propName in propNameList) - //{ - // _dbContext.Entry(entity).Property(propName).IsModified = true; - //} - - #endregion - } - - - /// - /// 部分字段更新 (只更新传递的字段名 new[] {nameof(User.Name), nameof(User.Age)) - /// new Dictionary() { ParentId = null, Code = "test",Id=Guid.Parse("8a90c96e-0776-4f7b-82a6-18933d339584")},new[] {nameof(Dictionary.Name), nameof(Dictionary.Age)) - /// - /// - /// 更新的字段数组 - /// - /// - /// - /// - public async Task UpdatePartialFieldsAsync(TEntity entity, string[] propertyNames, - bool autoSave = false, bool ignoreEntityNullProperty = true, params EntityVerifyExp[] verify) - { - await EntityVerifyAsync(false, verify, entity.Id); - - var entityEntry = _dbContext.Entry(entity); - entityEntry.State = EntityState.Detached; - - - foreach (var propertyName in propertyNames) - { - _dbContext.Entry(entity).Property(propertyName).IsModified = true; - } - - // 忽略空值 - IgnoreNullValues(ref entity, ignoreEntityNullProperty); - - return entityEntry.Entity; - } - - /// - /// 更新 排除某些字段的更新 排除方式: new[] {nameof(User.Name), nameof(User.Age) - /// - /// - /// - /// - /// - /// - /// - public async Task UpdateExcludeFields(TEntity entity, string[] propertyNames, bool autoSave = false, bool ignoreEntityNullProperty = true, params EntityVerifyExp[] verify) - { - - await EntityVerifyAsync(false, verify, entity.Id); - - var entityEntry = _dbContext.Entry(entity); - entityEntry.State = EntityState.Modified; - - - foreach (var propertyName in propertyNames) - { - _dbContext.Entry(entity).Property(propertyName).IsModified = false; - } - - // 忽略空值 - IgnoreNullValues(ref entity, ignoreEntityNullProperty); - - return entityEntry.Entity; - } - - /// - /// 忽略空值属性 - /// - /// - /// - private void IgnoreNullValues(ref TEntity entity, bool? ignoreNullValues = null) - { - var isIgnore = ignoreNullValues; - if (isIgnore == false) return; - - // 获取所有的属性 - var properties = _dbSet.EntityType.GetProperties(); - if (properties == null) return; - - foreach (var propety in properties) - { - var entityProperty = _dbContext.Entry(entity).Property(propety.Name); - var propertyValue = entityProperty?.CurrentValue; - var propertyType = entityProperty?.Metadata?.PropertyInfo?.PropertyType; - - // 判断是否是无效的值,比如为 null,默认时间,以及空 Guid 值 - var isInvalid = propertyValue == null - || (propertyType == typeof(DateTime) && propertyValue?.ToString() == new DateTime().ToString()) - || (propertyType == typeof(DateTimeOffset) && propertyValue?.ToString() == new DateTimeOffset().ToString()) - || (propertyType == typeof(Guid) && propertyValue?.ToString() == Guid.Empty.ToString()); - - if (isInvalid && entityProperty != null) - { - entityProperty.IsModified = false; - } - } - } - - - public async Task SaveChangesAsync(CancellationToken cancellationToken = default) - { - return await _dbContext.SaveChangesAsync(cancellationToken) > 0; - } - - public async ValueTask FindAsync(Guid id, CancellationToken cancellationToken = default) - { - return await _dbContext.FindAsync(id); - } - - //有可能是联合主键,本项目没用到,用Guid - public async ValueTask FindAsync(object[] keyValues, CancellationToken cancellationToken) - { - return await _dbContext.FindAsync(keyValues); - } - - public async Task FirstOrDefaultAsync(Expression> exp = null, bool ignoreQueryFilters = false) - { - - var query = _dbSet.AsQueryable(); - - if (ignoreQueryFilters) - { - query = query.IgnoreQueryFilters(); - } - if (exp == null) - return await query.FirstOrDefaultAsync().ConfigureAwait(false); - return await query.FirstOrDefaultAsync(exp).ConfigureAwait(false); - } - - - - public async Task> AddRangeAsync(IEnumerable entities) - { - foreach (var addEntity in entities) - { - await AddAsync(addEntity); - } - - return entities; - } - - + #region 异步查询 @@ -694,102 +760,34 @@ namespace IRaCIS.Core.Infra.EFCore return whereLambda == null ? await query.AsNoTracking().CountAsync() : await query.AsNoTracking().CountAsync(whereLambda); } - /// EF跟踪方式 更新,全字段更新 - public async Task UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) + public async ValueTask FindAsync(Guid id, CancellationToken cancellationToken = default) { - _dbSet.Update(entity); - - if (autoSave) - { - return await SaveChangesAsync(cancellationToken); - } - else - { - return false; - } + return await _dbContext.FindAsync(id); } - - /// EF跟踪方式 删除 - public async Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default) + //有可能是联合主键,本项目没用到,用Guid + public async ValueTask FindAsync(object[] keyValues, CancellationToken cancellationToken) { - _dbSet.Remove(entity); - - if (autoSave) - { - return await SaveChangesAsync(cancellationToken); - } - else - { - return false; - } + return await _dbContext.FindAsync(keyValues); } - - /// 批量删除,EF跟踪方式(所有查询出来,再删除 浪费性能,但是稽查 或者触发某些操作时,需要知道数据库实体信息 不可避免用这种) - public async Task TrackingBatchDeleteAsync(Expression> deleteFilter) + public async Task FirstOrDefaultAsync(Expression> exp = null, bool ignoreQueryFilters = false) { - var waitDeleteList = await _dbSet.IgnoreQueryFilters().Where(deleteFilter).ToListAsync(); - foreach (var deleteItem in waitDeleteList) + var query = _dbSet.AsQueryable(); + + if (ignoreQueryFilters) { - await DeleteAsync(deleteItem, false); + query = query.IgnoreQueryFilters(); } - + if (exp == null) + return await query.FirstOrDefaultAsync().ConfigureAwait(false); + return await query.FirstOrDefaultAsync(exp).ConfigureAwait(false); } - - /// 批量删除,相当于原生sql, 没用EF跟踪方式(所有查询出来,再删除 浪费性能) - public async Task BatchDeleteAsync(Expression> deleteFilter) - { - return await _dbSet.IgnoreQueryFilters().Where(deleteFilter).BatchDeleteAsync() > 0; - } - - - /// 批量更新,相当于原生sql, 没用EF跟踪方式(所有查询出来,再更新 浪费性能) - public async Task BatchUpdateAsync(Expression> where, - Expression> updateFactory) - { - - var bindings = ((MemberInitExpression)updateFactory.Body).Bindings.ToList(); - - if (typeof(IAuditUpdate).IsAssignableFrom(typeof(TEntity))) - { - var hasPropNameList = bindings.Select(t => t.Member.Name).ToList(); - - if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateTime))) - { - bindings.Add(Expression.Bind(typeof(TEntity).GetMember(nameof(IAuditUpdate.UpdateTime))[0], Expression.Constant(DateTime.Now))); - - } - - if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateUserId))) - { - bindings.Add(Expression.Bind(typeof(TEntity).GetMember(nameof(IAuditUpdate.UpdateUserId))[0], Expression.Constant(_userInfo.Id))); - - } - } - - - var member = Expression.MemberInit(Expression.New(typeof(TEntity)), bindings); - - var factory = Expression.Lambda>(member, Expression.Parameter(typeof(TEntity), "x")); - - - return await _dbSet.IgnoreQueryFilters().Where(where).BatchUpdateAsync(factory) > 0; - - - - } - - - - - #endregion - #region 非异步部分 public TEntity ImageFind(Guid id, Type type) @@ -886,6 +884,11 @@ namespace IRaCIS.Core.Infra.EFCore return _dbSet.AsNoTracking().ProjectTo(configuration, parameters, membersToExpand); } + + #endregion + + #region 待废弃 + /// /// 仅仅供字典表插入使用,因为efcore 动态映射列的问题 /// @@ -952,6 +955,9 @@ namespace IRaCIS.Core.Infra.EFCore } } + + + #endregion }