如何将遗留数据库搜索逻辑中的重复代码重构为简洁方法?
问题描述
对接遗留数据库时,搜索逻辑只能基于表中Level-1、Level-2这类行名称匹配,现有代码冗余严重,希望优化成更简洁的实现:
if (criteria.Levels.Contains("Level-1", StringComparer.CurrentCultureIgnoreCase)) { var filteredResult = allCachedItems .Where(x => !string.IsNullOrEmpty(x.Level1)); resultsSet.AddRange(filteredResult.Except(resultsSet)); } if (criteria.Levels.Contains("Level-2", StringComparer.CurrentCultureIgnoreCase)) { var filteredResult = allCachedItems .Where(x => !string.IsNullOrEmpty(x.Level2)); resultsSet.AddRange(filteredResult.Except(resultsSet)); } if (criteria.Levels.Contains("Level-3", StringComparer.CurrentCultureIgnoreCase)) { var filteredResult = allCachedItems .Where(x => !string.IsNullOrEmpty(x.Level3)); resultsSet.AddRange(filteredResult.Except(resultsSet)); }
需求说明:数据库表包含多个Level{X}列,适用记录会填充文本,不适用则为空;搜索表单传入Level-{x}格式的参数,需优化过滤逻辑,比如创建接收字符串和委托的通用方法,或其他简洁方案。
优化方案
方案1:封装通用过滤方法
写一个通用方法统一处理过滤、去重逻辑,避免重复代码:
// 替换YourItemType为实际的模型类型 private void AddLevelResults(IEnumerable<YourItemType> allCachedItems, HashSet<YourItemType> resultsSet, string levelParam, Func<YourItemType, string> levelPropertySelector) { if (criteria.Levels.Contains(levelParam, StringComparer.CurrentCultureIgnoreCase)) { var filtered = allCachedItems.Where(x => !string.IsNullOrEmpty(levelPropertySelector(x))); resultsSet.UnionWith(filtered); // 用HashSet的UnionWith替代AddRange+Except,性能更优 } }
调用时直接传入对应参数即可:
var resultsSet = new HashSet<YourItemType>(); AddLevelResults(allCachedItems, resultsSet, "Level-1", x => x.Level1); AddLevelResults(allCachedItems, resultsSet, "Level-2", x => x.Level2); AddLevelResults(allCachedItems, resultsSet, "Level-3", x => x.Level3);
方案2:映射字典批量处理
如果后续要新增Level-4、Level-5这类级别,只需在字典中添加映射,无需修改核心逻辑:
// 建立级别参数与属性选择器的映射(忽略大小写) var levelMappings = new Dictionary<string, Func<YourItemType, string>>(StringComparer.CurrentCultureIgnoreCase) { ["Level-1"] = x => x.Level1, ["Level-2"] = x => x.Level2, ["Level-3"] = x => x.Level3 }; var resultsSet = new HashSet<YourItemType>(); foreach (var levelParam in criteria.Levels) { if (levelMappings.TryGetValue(levelParam, out var selector)) { var filtered = allCachedItems.Where(x => !string.IsNullOrEmpty(selector(x))); resultsSet.UnionWith(filtered); } }
方案3:LINQ组合查询(一次性生成结果)
通过组合条件,用LINQ一次性筛选出所有符合要求的记录:
var validConditions = new List<Func<YourItemType, bool>>(); if (criteria.Levels.Contains("Level-1", StringComparer.CurrentCultureIgnoreCase)) validConditions.Add(x => !string.IsNullOrEmpty(x.Level1)); if (criteria.Levels.Contains("Level-2", StringComparer.CurrentCultureIgnoreCase)) validConditions.Add(x => !string.IsNullOrEmpty(x.Level2)); if (criteria.Levels.Contains("Level-3", StringComparer.CurrentCultureIgnoreCase)) validConditions.Add(x => !string.IsNullOrEmpty(x.Level3)); // 只要满足任一条件即可保留,Distinct自动去重 var resultsSet = allCachedItems.Where(item => validConditions.Any(cond => cond(item))).Distinct().ToList();
内容的提问来源于stack exchange,提问作者Username_null
相关产品推荐
相关产品推荐

