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

如何用LINQ处理关联多Subject的Form列表并按指定字段分组?

问题描述

我有一组Form对象,每个Form通过关联表FormSubjectLink与Subject对象关联。如果某个Form关联多个Subject,如何用LINQ返回一个列表,让该Form按关联的每个Subject各出现一次并携带对应SubjectId?另外,如何将列表中拥有相同TypeId和SubjectId的Form进行分组?

复现场景的代码如下:

public class Form
{
    public int Id { get; set; }
    public int TypeId { get; set; }
    public string Name { get; set; }
    public List<FormSubjectLink> FormSubjectLinks { get; set; }
    public int SubjectId { get; set; } // 用于存储拆分后的单个SubjectId
}

public class Subject
{
    public int Id { get; set; }
}

public class FormSubjectLink
{
    public int FormId { get; set; }
    public int SubjectId { get; set; }
}

public List<Form> forms = new List<Form>() {
new Form { Id = 1, TypeId = 1, Name = "FormA1", FormSubjectLinks = new List<FormSubjectLink>() { new FormSubjectLink { FormId = 1, SubjectId = 1 } } },
new Form { Id = 2, TypeId = 1, Name = "FormA2", FormSubjectLinks = new List<FormSubjectLink>() { new FormSubjectLink { FormId = 2, SubjectId = 1 } } },
new Form { Id = 3, TypeId = 1, Name = "FormA3", FormSubjectLinks = new List<FormSubjectLink>() { new FormSubjectLink { FormId = 3, SubjectId = 2 } } },
new Form { Id = 4, TypeId = 2, Name = "FormB1", FormSubjectLinks = new List<FormSubjectLink>() { new FormSubjectLink { FormId = 4, SubjectId = 1 }, new FormSubjectLink { FormId = 4, SubjectId = 2 }}}};

期望处理后返回IEnumerable<IGrouping<(int TypeId, int SubjectId), Form>>类型的结果,统计结果如下:

TypeIdSubjectIdForm Count
112
121
211
221

解决方案

1. 拆分Form与Subject的关联

使用SelectMany方法将每个Form与其关联的FormSubjectLink展开,生成每个Form对应单个SubjectId的条目。为避免修改原Form对象,可通过投影创建新的Form实例。

2. 按TypeId和SubjectId分组

使用GroupBy方法,以元组(TypeId, SubjectId)作为分组键,对拆分后的条目进行分组,得到目标类型的结果。

完整代码实现

// 拆分并分组
var groupedForms = forms
    // 展开每个Form的关联Subject,生成带对应SubjectId的Form条目
    .SelectMany(form => form.FormSubjectLinks.Select(link => new Form
    {
        Id = form.Id,
        TypeId = form.TypeId,
        Name = form.Name,
        FormSubjectLinks = form.FormSubjectLinks,
        SubjectId = link.SubjectId
    }))
    // 按(TypeId, SubjectId)分组
    .GroupBy(form => (form.TypeId, form.SubjectId));

// 验证统计结果
foreach (var group in groupedForms)
{
    Console.WriteLine($"TypeId: {group.Key.TypeId}, SubjectId: {group.Key.SubjectId}, Form Count: {group.Count()}");
}

代码说明

  • SelectMany:将每个Form的FormSubjectLinks集合拆分为单个条目,每个条目对应一个SubjectId,同时复制原Form的其他属性并设置SubjectId。
  • GroupBy:以(TypeId, SubjectId)元组作为分组键,将具有相同键的Form条目归为一组,返回的结果类型与需求完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 22:23:24