如何在ASP.NET / C#中将数据表转换为字典

下面的DataTable

 ClassID ClassName StudentID StudentName 1 A 1000 student666 2 B 1100 student111 5 C 1500 student777 1 A 1200 student222 2 B 1080 student999 

字典键由“ClassID,ClassName”组成,值由“StudentID,StudentName”组成。

 Dictionary d = new Dictionary(); foreach (DataRow dr in table.Rows) { string key=dr["ClassID"].ToString() + dr["ClassName"].ToString(); if (!d.ContainsKey(key)) { //Do something();...... } else { //Do something();...... } } foreach (var s in d.Keys) { Response.Write(s+"|+"+d[s]+"
"); }

有更快的方法吗?

假设密钥为’1,A’,值应为’1000,student666’和’1200,student222′

在这里。 使用Linq,您可以对它们进行分组,然后根据需要执行字符串连接。

 // Start by grouping var groups = table.AsEnumerable() .Select(r => new { ClassID = r.Field("ClassID"), ClassName = r.Field("ClassName"), StudentID = r.Field("StudentID"), StudentName = r.Field("StudentName") }).GroupBy(e => new { e.ClassID, e.ClassName }); // Then create the strings. The groups will be an IGrouping of anonymous objects but // intellisense will help you with that. foreach(var line in groups.Select(g => String.Format("{0},{1}|+{2}
", g.Key.ClassID, g.Key.ClassName, String.Join(" and ", g.Select(e => String.Format("{0},{1}", e.StudentID, e.StudentName)))))) { Response.Write(line); }

试试这个:

 Dictionary d = new Dictionary(); foreach (DataRow dr in table.Rows) { string key=dr["ClassID"].ToString() + "-" + dr["ClassName"].ToString(); string value=dr["StudentID"].ToString() + "-" + dr["StudentName"].ToString(); if (!d.ContainsKey(key)) { d.Add(key, value); } } 

参考 Dictionary.Add方法

或者试试Onkelborg的答案

如何使用复合键进行字典?

这里棘手的是复合键(ClassID,ClassName)。 一旦确定了这一点,就可以轻松搜索此站点以获得解决方案。

我建议使用这里指出的元组: 复合键字典

最简单的方法是使用ClassID | ClassName的字符串值作为键。 例如,对第一行的键使用字符串值“1 | A”,对第二行的键使用字符串值“2 | B”等。

这是可以给你一个想法的东西:

 using System; using System.Data; using System.Collections.Generic; namespace SO17416111 { class Class { public int Id { get; set; } public string Name { get; set; } } // Note that definition of Class and Student only differ by name // I'm assuming that Student can/will be expanded latter. // Otherwise it's possible to use a single class definition class Student { public int Id { get; set; } public string Name { get; set; } } class Program { static void Main() { DataTable table = GetData(); Dictionary> d = new Dictionary>(); foreach (DataRow dr in table.Rows) { // If it's possible to get null data from the DB the appropriate null checks // should also be performed here // Also depending on actual data types in your DB the code should be adjusted as appropriate Class key = new Class {Id = (int) dr["ClassID"], Name = (string) dr["ClassName"]}; Student value = new Student { Id = (int)dr["StudentID"], Name = (string)dr["StudentName"] }; if (!d.ContainsKey(key)) { d.Add(key, new List()); } d[key].Add(value); } foreach (var s in d.Keys) { foreach (var l in d[s]) { Console.Write(s.Id + "-" + s.Name + "-" + l.Id + "-" + l.Name + "\n"); } } } // You don't need this just use your datatable whereever you obtain it from private static DataTable GetData() { DataTable table = new DataTable(); table.Columns.Add("ClassID", typeof (int)); table.Columns.Add("ClassName", typeof (string)); table.Columns.Add("StudentID", typeof (int)); table.Columns.Add("StudentName", typeof (string)); table.Rows.Add(1, "A", 1000, "student666"); table.Rows.Add(2, "B", 1100, "student111"); table.Rows.Add(5, "C", 1500, "student777"); table.Rows.Add(1, "A", 1200, "student222"); table.Rows.Add(2, "B", 1080, "student999"); return table; } } } 

请注意,这可以作为控制台应用程序进行编译和测试 – 我用Console.Write替换了Response.Write 。 我也在生成测试DataTable,您应该能够使用已经存在于您的应用程序中的测试。 就Class / Student类而言,这里有几个选项:你可以有两个单独的类,你可以使用同一个类,或者你甚至可以使用一个Tuple类。 我建议你使用两个单独的类,因为它提高了可读性和可维护性。

请注意,如果您只需输出它们,则不需要字典或其他任何效果:

 // Add null checks and type conversions as appropriate foreach (DataRow dr in table.Rows) { Response.Write(dr["ClassID"] + "-" + dr["ClassName"] + "-" + dr["StudentID"] + "-" + dr["StudentName"] + "
"); }