如何修改C#代码移除委托依赖,实现单次调用合并更新实体多属性
实现方案
方案1:可选参数实现(适合单实体更新场景)
直接改造原有UpdateAsync方法,用可选参数控制要执行的更新逻辑,兼容原有单字段更新需求,同时支持合并更新:
/// <summary> /// 更新实体信息 /// </summary> /// <param name="aggregatorId">聚合根ID</param> /// <param name="baseEntityId">实体ID</param> /// <param name="newType">要更新的类型值,不传则不更新类型</param> /// <param name="newName">要更新的名称值,不传则不更新名称</param> public async Task UpdateAsync(Guid aggregatorId, Guid baseEntityId, IEnumerable<string> newType = null, string newName = null) { var someAggregator = await someAggregator.TryFindById(aggregatorId).ConfigureAwait(false); var baseEntity = someAggregator.ListBaseEntities().FirstOrDefault(x => x.Id == baseEntityId); // 处理实体不存在的边界情况 if (baseEntity == null) return; if (newType != null) { baseEntity.UpdateType(newType); } if (newName != null) { await baseEntity.UpdateNameAsync(newName).ConfigureAwait(false); } await aggregatorRepo.Save(someAggregator).ConfigureAwait(false); }
优势
- 无委托依赖,逻辑清晰易懂
- 完全兼容原有调用场景:原有的
UpdateBaseEntityTypeAsync、UpdateBaseEntityNameAsync可以直接复用该方法,不需要修改上层业务调用逻辑 - 支持合并更新:需要同时更新类型和名称时,同时传入两个参数即可一次调用完成操作
方案2:优化批量更新实现(适合多实体批量更新场景)
现有批量版本的核心问题是将保存操作放在了循环内,更新N个实体就会执行N次IO操作,同时用null判断是否更新存在歧义(比如业务需要把类型设置为空的场景会被当成不需要更新),优化后实现如下:
/// <summary> /// 实体更新意图,明确标识每个字段是否需要更新 /// </summary> public class BaseEntityUpdateIntent { public Guid Id { get; set; } public bool NeedUpdateType { get; set; } public IEnumerable<string> Type { get; set; } public bool NeedUpdateName { get; set; } public string Name { get; set; } } /// <summary> /// 批量更新实体信息 /// </summary> public async Task BatchUpdateAsync(Guid aggregatorId, List<BaseEntityUpdateIntent> updateIntents) { var someAggregator = await someAggregator.TryFindById(aggregatorId).ConfigureAwait(false); // 提前转为字典,避免循环内遍历查找,性能更优 var entityDict = someAggregator.ListBaseEntities().ToDictionary(x => x.Id); foreach (var intent in updateIntents) { if (!entityDict.TryGetValue(intent.Id, out var baseEntity)) { continue; } if (intent.NeedUpdateType) { baseEntity.UpdateType(intent.Type); } if (intent.NeedUpdateName) { await baseEntity.UpdateNameAsync(intent.Name).ConfigureAwait(false); } } // 所有更新完成后统一保存,减少IO次数 await aggregatorRepo.Save(someAggregator).ConfigureAwait(false); }
优势
- 解决了null判断的歧义问题,支持将字段合法设置为空的业务场景
- 批量操作仅执行一次保存,性能提升明显
- 后续新增更新字段时,仅需要扩展
BaseEntityUpdateIntent和对应逻辑即可
如果后续需要扩展更多更新逻辑且不想频繁修改核心更新方法,可引入访问者模式实现,不过对于仅两个更新字段的场景属于过度设计,可按需选择。
内容的提问来源于stack exchange,提问作者Cirus
相关产品推荐
相关产品推荐

