更优雅的方式在C#中的结构中对DataTable数据进行分组(使用Linq?)

时间:2018-01-19 07:43:13

标签: c# linq datatable

我有一组数据存储在数据库表中,我想将其转换为group-struct列表,每个包含数据数组。

我可以使用相当长的方法来做到这一点。我想知道是否有更紧凑的方法来实现这一目标?我怀疑Linq应该是完美的这种操作,但我真的不知道如何开始。

以下示例说明了我目前正在做的事情。我的真实数据更复杂。

数据将存储在像

这样的结构中
public struct GroupData
{
    private string aString;
    private int anInt;

    public GroupData(string aString, int anInt)
    {
        this.aString = aString;
        this.anInt = anInt;
    }
}

同样存储在Group-struct

public struct Group
{
    private string groupId;
    private GroupData[] groupData;

    public Group(string groupId, GroupData[] groupData)
    {
       this.groupId = groupId;
       this.groupData = groupData;
    }
}

我目前正在做这个

//Create some dummy data
DataTable table = new DataTable();
table.Columns.Add("GROUP_ID", typeof(string));
table.Columns.Add("A_STRING", typeof(string));
table.Columns.Add("AN_INT", typeof(int));

table.Rows.Add("A", "this_is_A2", 7);
table.Rows.Add("A", "this_is_A2", 4);
table.Rows.Add("B", "this_is_B1", 3);
table.Rows.Add("C", "this_is_C1", 1);
table.Rows.Add("D", "this_is_D1", 3);
table.Rows.Add("D", "this_is_D2", 2);

//Create list of groups with arrays of groupdata
string theString, theGroupId;
int theInt;
List<Group> theGroups = new List<Group>();
List<GroupData> groupDataList;
Dictionary<string, List<GroupData>> groupDataDict = new Dictionary<string, List<GroupData>>();

//Read all rows and convert to structs
for (int i = 0; i < table.Rows.Count; i++)
{
    theGroupId = (string)table.Rows[i]["GROUP_ID"];
    theString = (string)table.Rows[i]["A_STRING"];
    theInt = (int)table.Rows[i]["AN_INT"];

    //Collect all GroupData into their respective Groups
    if (!groupDataDict.TryGetValue(theGroupId, out groupDataList))
    {
        groupDataList = new List<GroupData>();
        groupDataDict.Add(theGroupId, groupDataList);
    }
    groupDataList.Add(new GroupData(theString, theInt));
}

//Insert each group into the list
foreach (KeyValuePair<string, List<GroupData>> kv in groupDataDict)
    theGroups.Add(new Group(kv.Key, kv.Value.ToArray()));

我看到我的问题与此帖Group by in LINQ密切相关,我想我可以先将数据表转换为列表,然后使用指定的方法。但理想情况下,我想绕过首先转换到列表并直接在DataTable上运行的步骤。

1 个答案:

答案 0 :(得分:1)

虽然我强烈建议像大多数现代应用程序一样从DataTable切换到使用模型,但Microsoft在System.Data.DataTableExtensions中提供了AsEnumerable()扩展方法,这就是使用LINQ所需的全部内容DataTable

//Create some dummy data
DataTable table = new DataTable();
table.Columns.Add("GROUP_ID", typeof(string));
table.Columns.Add("A_STRING", typeof(string));
table.Columns.Add("AN_INT", typeof(int));

table.Rows.Add("A", "this_is_A2", 7);
table.Rows.Add("A", "this_is_A2", 4);
table.Rows.Add("B", "this_is_B1", 3);
table.Rows.Add("C", "this_is_C1", 1);
table.Rows.Add("D", "this_is_D1", 3);
table.Rows.Add("D", "this_is_D2", 2);

var groups = (from dt in table.AsEnumerable()
              group dt by dt.Field<string>("GROUP_ID") into g
              select new { 
                  GroupID = g.Key, 
                  GroupData = g.Select(i => i.Field<int>("AN_INT")) }
              ).ToList();

参考:LINQ query on a DataTable