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

C# Lambda按Date与UserId分组行转列生成新集合的实现方法

实现方案

步骤1:定义行转列后的目标DTO类

首先定义用于接收转换结果的类,属性对应你需要的目标字段:

public class TransactionPivotResult
{
    // 分组维度字段
    public DateTime Date { get; set; }
    public int UserId { get; set; }
    // 行转列后的TypeId对应值字段,类型和原始Value保持一致,使用可空类型存储无匹配的空值
    public decimal? TypeId1 { get; set; }
    public decimal? TypeId2 { get; set; }
    public decimal? TypeId3 { get; set; }
    public decimal? TypeId4 { get; set; }
}

步骤2:对分组结果做投影转换

你已经拿到了按Transaction_Date和User_Id分组的结果,直接通过Select方法对每个分组做字段匹配即可:

var pivotResult = groupTranDate.Select(g => new TransactionPivotResult
{
    Date = g.Key.Transaction_Date,
    UserId = g.Key.User_Id,
    // 匹配每个TypeId对应的Value,无匹配则返回空
    TypeId1 = g.FirstOrDefault(x => x.TypeId == 1)?.Value,
    TypeId2 = g.FirstOrDefault(x => x.TypeId == 2)?.Value,
    TypeId3 = g.FirstOrDefault(x => x.TypeId == 3)?.Value,
    TypeId4 = g.FirstOrDefault(x => x.TypeId == 4)?.Value
}).ToList();

优化建议:直接在EF侧完成转换(减少内存占用)

如果不需要保留原始分组数据,可以把投影逻辑直接写到EF查询链路中,不需要把全量分组数据加载到内存后再处理,性能更高:

var pivotResult = db.System_Transactions
    .GroupBy(g => new { g.Transaction_Date, g.User_Id })
    .Select(g => new TransactionPivotResult
    {
        Date = g.Key.Transaction_Date,
        UserId = g.Key.User_Id,
        TypeId1 = g.Where(x => x.TypeId == 1).Select(x => (decimal?)x.Value).FirstOrDefault(),
        TypeId2 = g.Where(x => x.TypeId == 2).Select(x => (decimal?)x.Value).FirstOrDefault(),
        TypeId3 = g.Where(x => x.TypeId == 3).Select(x => (decimal?)x.Value).FirstOrDefault(),
        TypeId4 = g.Where(x => x.TypeId == 4).Select(x => (decimal?)x.Value).FirstOrDefault()
    }).ToList();

注意:如果同一个Date+UserId下存在同一个TypeId的多条数据,可以根据业务需求将FirstOrDefault替换为Sum、Average等聚合函数实现对应逻辑。


内容的提问来源于stack exchange,提问作者นพรัตน์ ทองเนื่อแปด

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 04:48:01