You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用LINQ填充含子集合的ProjectApprovalViewModel?

解决方案:用LINQ分组转换扁平数据至嵌套ViewModel

没问题,这事儿用LINQ的GroupBy就能完美解决,我给你拆解一下实现步骤和代码示例:

1. 先明确相关结构(方便对照)

首先,假设你的扁平查询结果对应如下实体类(如果是EF查询,也可以直接用数据库实体或匿名类型,这里用强类型示例更清晰):

// 扁平数据的实体/DTO
public class FlatApprovalRecord
{
    public int ProjectApprovalHeaderId { get; set; }
    public string StepName { get; set; }
    public string Status { get; set; }
}

你的ViewModel定义(和你给出的完全一致):

public class ProjectApprovalHeaderVM
{
    public int ProjectApprovalHeaderId { get; set; }
    public List<ProjectApprovalStepsVM> ProjectApprovalHistorySteps { get; set; }
}

public class ProjectApprovalStepsVM
{
    public string StepName { get; set; }
    public string Status { get; set; }
}

2. 核心LINQ转换代码

不管是内存中的集合,还是EF Core从数据库直接查询的结果,都可以用下面的代码完成转换:

// 假设flatApprovalRecords是你的扁平查询结果集合(IEnumerable<FlatApprovalRecord>)
var headerViewModels = flatApprovalRecords
    // 按ProjectApprovalHeaderId分组,把同ID的步骤归为一组
    .GroupBy(record => record.ProjectApprovalHeaderId)
    // 遍历每个分组,转换为目标ViewModel
    .Select(group => new ProjectApprovalHeaderVM
    {
        ProjectApprovalHeaderId = group.Key, // 分组键就是当前组的HeaderId
        // 将分组内的扁平记录转换为StepsVM子集合
        ProjectApprovalHistorySteps = group.Select(stepRecord => new ProjectApprovalStepsVM
        {
            StepName = stepRecord.StepName,
            Status = stepRecord.Status
        }).ToList()
    })
    .ToList();

3. 关键逻辑解释

  • GroupBy(record => record.ProjectApprovalHeaderId):把所有扁平数据按审批头ID聚合,每个分组包含同一个审批头的所有步骤记录。
  • 分组后的group.Key就是当前组的审批头ID,直接赋值给ViewModel的对应属性。
  • 对分组内的每条记录,映射为ProjectApprovalStepsVM对象,最后通过ToList()转换为子集合。

额外注意事项

如果是在EF Core中直接执行数据库查询,这种GroupBy+投影的写法是可以被EF Core解析为SQL的(只要分组键是简单类型),不需要先把数据拉到内存。如果遇到EF Core无法解析的特殊场景,再加上.AsEnumerable()切换到内存中处理即可。

内容的提问来源于stack exchange,提问作者TrevorGoodchild

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:23:45