C#中如何对嵌套集合Options执行GetRange范围截取
问题描述
现有从数据库读取嵌套集合数据的业务逻辑,需要对每个筛选条目的嵌套集合做分页截取,相关定义与代码如下:
相关模型定义
public class FilterOptionDto { public Guid Id { get; set; } public string FilterName { get; set; } public ICollection<OptionDto> Options { get; set; } }
原有业务代码
public async Task<List<FilterOptionDto>?> SetFilterOptions(SetFilterOptionsInputDto input) { var useCase = await _dbContext.UseCases.FirstOrDefaultAsync(x => x.Id == input.UseCaseId); var dimensionsConfiguration = _analysisDimensionsProvider.AnalysisDimensionsSetting.FirstOrDefault(x => x.FieldNameDomain == input.Name); if (dimensionsConfiguration != null) { var filters = _mapper.Map<List<FilterOptionDto>>(await _dbContext.VwAnalysisUseCaseFilters.Where(x => x.JobId == useCase!.JobId && x.IsUseCaseFilter == true && x.FilterType == "multiselect" && x.IsAvailable && x.FieldNameDomain == input.Name) .ToListAsync()); foreach (FilterOptionDto item in filters) { item.Options = await GetOptions(useCase?.JobId, dimensionsConfiguration.Source, dimensionsConfiguration.FieldNameDomain); } if (!string.IsNullOrEmpty(input.SearchInput)) { filters = filters.Where(x => x.Options.Any(x => x.Value.Contains(input.SearchInput))).ToList(); } // 待实现位置:需要对每个筛选项下的Options集合,从input.Offset偏移位置开始截取3条数据 // filters = filters.Where(x => x.FilterName.Contains(input.Name)).ToList() // .GetRange(input.Offset, input.Offset + 3); return filters; } return null; }
需求:在代码标注的待实现位置,对每个FilterOptionDto下嵌套的Options集合做范围截取,根据传入的input.Offset参数,从偏移量起始位置取3条数据。
实现方法
注意两个核心要点:
GetRange是List<T>的专属方法,第一个参数是起始索引,第二个参数是截取的元素个数,不是结束索引,原注释里的参数写法有误。- 截取操作是针对每个筛选项内部的
Options集合,不是最外层的filters列表,需要遍历每个筛选项单独处理,同时要做索引越界判断避免运行时报错。
将注释位置的代码替换为以下内容即可:
foreach (var filterItem in filters) { // ICollection没有GetRange方法,先转为List var optionList = filterItem.Options.ToList(); int skip = input.Offset; // 偏移量超过选项总条数时,直接返回空集合 if (skip >= optionList.Count) { filterItem.Options = new List<OptionDto>(); continue; } // 计算实际可截取长度,剩余不足3条时取全部剩余项 int takeLength = Math.Min(3, optionList.Count - skip); filterItem.Options = optionList.GetRange(skip, takeLength); }
注意事项
- 如果
Options本身从GetOptions方法返回的就是List<OptionDto>类型,可以省略ToList()转换步骤。 - 越界判断必须添加:当偏移量大于集合总长度、或者偏移后剩余元素不足3个时,
GetRange会抛出ArgumentOutOfRangeException,上述代码已经处理了这两类边界场景。
内容的提问来源于stack exchange,提问作者Eugene Sukh
相关产品推荐
相关产品推荐

