分组后多行合并为一行(string.Join)


核心需求

按某个字段分组后,把组内其他字段的值拼接成一个字符串,实现”多条合并成一条”的效果。

比如按 name 分组,把每组所有人的 id 合并为 "1,4" 这样的格式。


写法一:使用 let 存储每组的集合

var qg = from qd in q
         group qd by new
         {
             qd.bh
         } into g
         let ids = g.Select(m => m.id)          // 提取每组的 id 集合
         select new
         {
             g.Key.bh,
             Ids = string.Join(",", ids),       // 拼接为 "1,4"
             id2 = string.Join(",", g.Select(m => m.id))  // 直接写也行
         };Code language: JavaScript (javascript)

写法二:直接在 select 中拼接(不用 let

using (var db = new DataClasses1DataContext())
{
    var q = from s in db.Student
            group s by s.sex into g
            let info = g.Select(m => m.name + ":" + m.age)
            select new
            {
                sex = g.Key,
                count = g.Count(),
                msg = string.Join(",", info),                              // 用 let 变量
                msg2 = string.Join("|", g.Select(m => m.name + ":" + m.age)) // 直接拼接
            };
    var list = q.ToList();
}Code language: JavaScript (javascript)

执行结果示意

假设数据:

idnameagesex
1张三20
4张三22
2李四21
3赵六19

name 分组后:

namecountIds
张三21,4
李四12
赵六13

sex 分组后:

sexcountmsg
3张三:20,李四:21,张三:22
1赵六:19

执行机制说明

string.Join 在 LINQ to SQL 中无法翻译为 SQL 函数。

实际执行流程:

1. 数据库执行 GROUP BY 查询,返回每组的主键/字段
2. 数据加载到内存后,客户端执行 string.Join 拼接

等效于:

var list = q.ToList(); // 先查出来
var result = list.Select(g => new
{
    g.Key.bh,
    Ids = string.Join(",", g.Select(m => m.id)) // 内存中拼接
});Code language: JavaScript (javascript)

如果需要在数据库端完成拼接(SQL Server)

可以用 FOR XML PATH 方式,通过 ExecuteQuery 执行原生 SQL:

SELECT bh,
       STUFF((
           SELECT ',' + CAST(id AS VARCHAR)
           FROM Student t2
           WHERE t2.bh = t1.bh
           FOR XML PATH('')
       ), 1, 1, '') AS Ids
FROM Student t1
GROUP BY bhCode language: PHP (php)

LINQ to SQL 本身不支持这种写法,需要 ExecuteQuery 或升级到 Entity Framework Core(支持 string_agg)。


关键要点

要点说明
let vs 直接写两种方式等效,let 可读性更好,适合复用
执行位置string.Join内存中执行,不是 SQL 端
数据量分组数不多时没问题;分组数很大时注意内存消耗
SQL Server 2017+可用 STRING_AGG 函数(需 ExecuteQuery
替代方案先查到内存再拼接,或数据库端用 FOR XML PATH / STRING_AGG

总结:let + string.Join 是 LINQ to SQL 中”分组后多行合并为一行”的常用写法,简洁直观,适合中小数据量场景。

是否需要我帮你演示 SQL Server 端 STRING_AGG + ExecuteQuery​ 的完整写法,或者讲解 分组后拼接 + 分页​ 的处理方式?

按某个字段分组后,把组内其他字段的值拼接成一个字符串,实现”多条合并成一条”的效果。

比如按 name 分组,把每组所有人的 id 合并为 "1,4" 这样的格式。


写法一:使用 let 存储每组的集合

var qg = from qd in q
         group qd by new
         {
             qd.bh
         } into g
         let ids = g.Select(m => m.id)          // 提取每组的 id 集合
         select new
         {
             g.Key.bh,
             Ids = string.Join(",", ids),       // 拼接为 "1,4"
             id2 = string.Join(",", g.Select(m => m.id))  // 直接写也行
         };Code language: JavaScript (javascript)

写法二:直接在 select 中拼接(不用 let

using (var db = new DataClasses1DataContext())
{
    var q = from s in db.Student
            group s by s.sex into g
            let info = g.Select(m => m.name + ":" + m.age)
            select new
            {
                sex = g.Key,
                count = g.Count(),
                msg = string.Join(",", info),                              // 用 let 变量
                msg2 = string.Join("|", g.Select(m => m.name + ":" + m.age)) // 直接拼接
            };
    var list = q.ToList();
}Code language: JavaScript (javascript)

执行结果示意

假设数据:

idnameagesex
1张三20
4张三22
2李四21
3赵六19

name 分组后:

namecountIds
张三21,4
李四12
赵六13

sex 分组后:

sexcountmsg
3张三:20,李四:21,张三:22
1赵六:19

执行机制说明

string.Join 在 LINQ to SQL 中无法翻译为 SQL 函数。

实际执行流程:

1. 数据库执行 GROUP BY 查询,返回每组的主键/字段
2. 数据加载到内存后,客户端执行 string.Join 拼接

等效于:

var list = q.ToList(); // 先查出来
var result = list.Select(g => new
{
    g.Key.bh,
    Ids = string.Join(",", g.Select(m => m.id)) // 内存中拼接
});Code language: JavaScript (javascript)

如果需要在数据库端完成拼接(SQL Server)

可以用 FOR XML PATH 方式,通过 ExecuteQuery 执行原生 SQL:

SELECT bh,
       STUFF((
           SELECT ',' + CAST(id AS VARCHAR)
           FROM Student t2
           WHERE t2.bh = t1.bh
           FOR XML PATH('')
       ), 1, 1, '') AS Ids
FROM Student t1
GROUP BY bhCode language: PHP (php)

LINQ to SQL 本身不支持这种写法,需要 ExecuteQuery 或升级到 Entity Framework Core(支持 string_agg)。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注