如何为LINQ查询的匿名类型创建适配的ViewModel
解决方案
1. 重新定义ViewModel
你需要一个能承载年份和对应月度能耗列表的ViewModel,因为你的LINQ查询是按年份分组的,每个分组包含年份和该年份下的所有月度数据:
public class YearlyEnergyUsageViewModel { // 分组的年份 public int Year { get; set; } // 该年份对应的所有月度能耗数据 public IEnumerable<UsagePerMonth> MonthlyUsages { get; set; } }
2. 修改LINQ查询
原查询返回的是匿名分组的集合,无法匹配ViewModel。需要修改查询,将分组结果投影到上面定义的ViewModel中,同时添加指定Customer.Id的筛选条件(符合你的最终目标):
// 替换为实际要查询的客户ID int targetCustomerId = 1; var yearlyEnergyUsageList = from e in _context.EnergyUsages // 筛选指定客户的能耗记录 where e.CustomerID == targetCustomerId // 关联月度能耗表 join u in _context.UsagesPerMonth on e.Id equals u.EnergyUsageId into monthlyUsagesGroup // 按EnergyUsage的Date字段提取年份分组 group monthlyUsagesGroup by e.Date.Year into yearGroup // 投影到ViewModel select new YearlyEnergyUsageViewModel { Year = yearGroup.Key, // 展开分组中的月度数据,过滤空条目 MonthlyUsages = yearGroup.SelectMany(u => u).Where(u => u != null) }; // 执行查询并返回视图 return View(yearlyEnergyUsageList.ToList());
3. 调整视图的模型类型
视图需要接收IEnumerable<YearlyEnergyUsageViewModel>类型的模型,修改视图顶部的模型声明:
@model IEnumerable<Jullerup.Models.YearlyEnergyUsageViewModel>
4. 视图渲染示例
你可以这样在视图中遍历数据生成表格:
<table> <thead> <tr> <th>年份</th> <th>月份</th> <th>能耗值</th> <th>能源类型</th> </tr> </thead> <tbody> @foreach (var yearGroup in Model) { foreach (var monthlyUsage in yearGroup.MonthlyUsages) { <tr> <!-- 仅在该年份的第一行显示年份,合并单元格 --> @if (monthlyUsage == yearGroup.MonthlyUsages.First()) { <td rowspan="@yearGroup.MonthlyUsages.Count()">@yearGroup.Year</td> } <td>@monthlyUsage.Month</td> <td>@monthlyUsage.Usage</td> <td>@monthlyUsage.EnergyType</td> </tr> } } </tbody> </table>
原方案报错原因
- 原ViewModel仅包含月度数据集合,缺少分组所需的年份字段,无法承载分组查询结果。
- 原LINQ查询返回的是
List<IEnumerable<UsagePerMonth>>类型集合,和视图期望的IEnumerable<EnergyUsageViewModel>类型完全不匹配,因此抛出类型转换异常。
内容的提问来源于stack exchange,提问作者Kudue
相关产品推荐
相关产品推荐

