如何将DataReader/DataTable数据加载到按Type分组的自定义对象中?
问题:将DataReader数据按Type分组加载到自定义对象中
现有DataReader数据
| ID | Description | Type |
|---|---|---|
| 1 | Test1 | 1 |
| 2 | Test2 | 2 |
| 3 | Test3 | 1 |
| 4 | Test4 | 3 |
| 5 | Test5 | 3 |
目标对象结构
type: 1 id:1 desc:Test1 id:3 desc:Test3 type: 2 id:2 desc:Test2 type: 3 id:4 desc:Test4 id:5 desc:Test5
已定义的C#类
public class Val { public string type { get; set; } public List<valItems> valItems{ get; set; } } public class valItems { public string id { get; set; } public string desc { get; set; } }
当前遇到的瓶颈
你目前的ReadData函数框架还没实现按Type分组的逻辑,需要补充代码来避免重复创建同一Type的Val对象:
ReadData() { //some code if (reader.HasRows) { while(reader.Read()) { dropdown.Add(new Dropdown { Type = Convert.ToString(reader["type"]), valItems= }), }); } }
解决方案
这里提供两种可行的实现方式,你可以根据自己的习惯和场景选择:
方案一:直接遍历DataReader分组(内存更高效)
我们可以用一个字典来跟踪已经创建过的Type分组,确保同一个Type只对应一个Val对象,避免重复创建:
public List<Val> ReadData(IDataReader reader) { // 字典的键是Type字符串,值是对应的Val对象,用于快速查找分组 var typeGroups = new Dictionary<string, Val>(); if (reader.HasRows) { while (reader.Read()) { // 读取当前行的字段值 string currentType = Convert.ToString(reader["Type"]); string currentId = Convert.ToString(reader["ID"]); string currentDesc = Convert.ToString(reader["Description"]); // 如果当前Type还没有对应的分组,创建新的Val对象并加入字典 if (!typeGroups.ContainsKey(currentType)) { typeGroups[currentType] = new Val { type = currentType, valItems = new List<valItems>() }; } // 将当前行的数据添加到对应分组的valItems列表中 typeGroups[currentType].valItems.Add(new valItems { id = currentId, desc = currentDesc }); } } // 将字典中的Val对象转换为List返回,就是我们需要的分组结果 return typeGroups.Values.ToList(); }
方案二:转换为DataTable后用LINQ分组(代码更简洁)
如果更习惯使用DataTable和LINQ操作,可以先把DataReader转换为DataTable,再通过GroupBy完成分组:
using System.Data; using System.Linq; public List<Val> ReadDataWithDataTable(IDataReader reader) { // 将DataReader的数据加载到DataTable中 DataTable dataTable = new DataTable(); dataTable.Load(reader); // 用LINQ按Type分组,并映射到我们的自定义对象 var groupedResult = dataTable.AsEnumerable() .GroupBy(row => row.Field<string>("Type")) .Select(group => new Val { type = group.Key, valItems = group.Select(row => new valItems { id = row.Field<string>("ID"), desc = row.Field<string>("Description") }).ToList() }) .ToList(); return groupedResult; }
方案对比
- 方案一:不需要额外创建DataTable,内存占用更低,适合数据量较大的场景
- 方案二:借助LINQ让代码更简洁易读,开发效率更高,适合数据量不大的场景
内容的提问来源于stack exchange,提问作者rgoal
相关产品推荐
相关产品推荐

