Linq to Sql自连接分组查询:按MachineId聚合机器版本与详情
修正Linq to Sql分组查询逻辑
现有实体类
public class MachineUpdate { public int MachineUpdateId { get; set;} public int MachineId { get; set;} public string MachineName { get; set; } public DateTime PublishDate { get; set; } public string PublishedBy { get; set; } public bool IsCorrect { get; set; } public decimal Version { get; set; } } public class DetailedMachine { public int DetailedMachineId { get; set;} public int MachineUpdateId { get; set;} public string ConfigurationInfo { get; set; } }
业务关系与数据示例
- 每台机器对应多个版本更新记录,每个更新可关联多条详情数据。
MachineUpdate表数据
| MachineUpdateId | MachineId | MachineName | PublishDate | PublishedBy | Version | IsCorrect |
|---|---|---|---|---|---|---|
| 1 | 1 | machine1 | 12/01/2022 | user1 | 1.00 | 1 |
| 2 | 1 | machine1 | 12/02/2022 | user1 | 1.01 | 1 |
| 3 | 2 | machine2 | 15/01/2022 | user2 | 1.00 | 1 |
DetailedMachine表数据
| DetailedMachineId | MachineUpdateId | ConfigurationInfo |
|---|---|---|
| 1 | 1 | blah blah got changed |
| 2 | 1 | blah blah got changed |
目标输出结构
需按MachineId分组生成List<MachineData>集合,预期结果为2条记录(对应machine1和machine2):
public class MachineData { public int MachineUpdateId { get; set;} public string PublishedBy { get; set; } public int VersionCount { get; set; } public List<Version> Versions { get; set; } public List<DetailedMachine> DetailedMachine { get; set; } } public class Version { public int MachineUpdateId { get; set;} public string MachineName { get; set; } public DateTime PublishDate { get; set; } public string PublishedBy { get; set; } public decimal Version { get; set; } }
原查询问题
原查询未按MachineId分组,而是遍历每条MachineUpdate生成MachineData,导致结果重复;VersionCount未赋值;DetailedMachine仅关联当前单条MachineUpdate的详情,不符合按机器汇总的需求。
修正后的查询逻辑
// 按MachineId分组,筛选有效更新记录 var groupedData = from mu in _dbContext.MachineUpdate where mu.IsCorrect group mu by mu.MachineId into machineGroup select new { MachineId = machineGroup.Key, AllUpdates = machineGroup.ToList() }; // 转换为目标结构并关联详情数据 var result = (from groupItem in groupedData // 取该机器第一条更新的公共字段,若需最新更新可改为OrderByDescending(p => p.PublishDate).First() let firstUpdate = groupItem.AllUpdates.First() select new MachineData { MachineUpdateId = firstUpdate.MachineUpdateId, PublishedBy = firstUpdate.PublishedBy, VersionCount = groupItem.AllUpdates.Count, Versions = groupItem.AllUpdates.Select(v => new Version { MachineUpdateId = v.MachineUpdateId, MachineName = v.MachineName, PublishDate = v.PublishDate, PublishedBy = v.PublishedBy, Version = v.Version }).ToList(), DetailedMachine = (from dm in _dbContext.DetailedMachine join mu in groupItem.AllUpdates on dm.MachineUpdateId equals mu.MachineUpdateId select new DetailedMachine { MachineUpdateId = dm.MachineUpdateId, ConfigurationInfo = dm.ConfigurationInfo }).ToList() }).ToList();
关键修正点
- 按MachineId分组:通过
group mu by mu.MachineId实现机器维度的汇总,确保每个机器对应一条MachineData。 - VersionCount赋值:直接取分组内更新记录的数量
groupItem.AllUpdates.Count。 - 关联全量详情:通过分组内所有
MachineUpdateId关联DetailedMachine,获取该机器所有更新对应的详情数据。 - 公共字段取值:取分组内第一条更新的标识与发布人信息,可根据业务需求调整为最新更新的字段。
内容的提问来源于stack exchange,提问作者csharpnewbie programmer
相关产品推荐
相关产品推荐

