在.NET Core中实现模型字段Nights与Visits除法运算并通过API返回结果的方法咨询
在.NET Core中计算年度每晚访问量并通过API返回结果
首先,你现有代码用嵌套循环聚合同一年的Visits,逻辑偏繁琐且效率偏低(时间复杂度为O(n²)),我们可以用LINQ的分组功能简化这个过程,同时轻松实现Nights除以Visits的计算需求。
步骤1:定义返回结果模型(推荐方案)
为了清晰返回API所需的计算结果,建议创建专门的DTO(数据传输对象),避免修改原模型或接口:
public class AnnualNightVisitStats { public int YearNo { get; set; } public double TotalNights { get; set; } public double TotalVisits { get; set; } public double NightsPerVisit { get; set; } // 核心计算结果:每晚访问量 }
步骤2:优化仓储层的聚合与计算逻辑
用GroupBy按年份分组,直接聚合Nights和Visits的总和,同时计算比值。这里要特别注意除以零的异常处理(如果某一年的Visits总和为0,直接计算会抛出运行时错误):
var datas = mapper.Map<List<ILocalDefaultIndicatorNights>>(records); // 按YearNo分组,聚合数据并计算结果 var result = datas .GroupBy(item => item.YearNo) .Select(group => { var totalVisits = group.Sum(item => item.Visits); return new AnnualNightVisitStats { YearNo = group.Key, TotalNights = group.Sum(item => item.Nights), TotalVisits = totalVisits, // 处理Visits为0的情况,这里根据业务需求返回0,也可以将NightsPerVisit设为double?返回null NightsPerVisit = totalVisits == 0 ? 0 : group.Sum(item => item.Nights) / totalVisits }; }) .OrderBy(stats => stats.YearNo) .ToList(); return result;
如果不想新增DTO,修改原接口的方案
如果你希望直接在原ILocalDefaultIndicatorNights接口上扩展,可以先添加计算属性:
public interface ILocalDefaultIndicatorNights { int YearNo { get; set; } double Nights { get; set; } double Visits { get; set; } double NightsPerVisit { get; set; } // 新增计算结果字段 }
然后调整仓储层代码:
var datas = mapper.Map<List<ILocalDefaultIndicatorNights>>(records); var aggregatedData = datas .GroupBy(item => item.YearNo) .Select(group => { var totalVisits = group.Sum(item => item.Visits); // 假设你有接口的具体实现类,比如LocalDefaultIndicatorNights return new LocalDefaultIndicatorNights { YearNo = group.Key, Nights = group.Sum(item => item.Nights), Visits = totalVisits, NightsPerVisit = totalVisits == 0 ? 0 : group.Sum(item => item.Nights) / totalVisits }; }) .OrderBy(item => item.YearNo) .ToList<ILocalDefaultIndicatorNights>(); return aggregatedData;
方案优势
- 逻辑更清晰:用LINQ分组代替嵌套循环,代码可读性大幅提升
- 效率更高:
GroupBy的时间复杂度为O(n),远优于原代码的O(n²) - 异常处理更完善:提前处理了
Visits为0的情况,避免运行时抛出DivideByZeroException
内容的提问来源于stack exchange,提问作者Irakli925
相关产品推荐
相关产品推荐

