从对象列表创建反转的数据表

时间:2015-07-24 03:45:48

标签: c# sql linq datatable datasource

我有ClassGrades表,其中包含以下字段:
Id,ClassId,学生,比赛,科学,历史,英语

我使用如下函数检索所有正确的行:

IList<ClassGrade> classGrades = ClassService.GetClassGrades(classId: 1);

此列表中包含ClassGrade对象,如下所示:
Id = 1,ClassId = 1,Student ='Mark',Math = 50.6,Science = 21.8,History = 70.7,English = 80.1
Id = 2,ClassId = 1,Student ='Jacob',Math = 70.8,Science = 19.4,History = 78.7,English = 11.1
Id = 3,ClassId = 1,学生='劳伦',数学= 21.9,科学= 61.1,历史= 99.5,英语= 12.1
Id = 4,ClassId = 1,学生='莎拉',数学= 81.7,科学= 65.2,历史= 73.7,英语= 65.1

我需要翻转这些结果,以便学生是列,而成绩是行的主题,然后将其绑定到我页面上的网格。 我想创建一个新的数据表并根据需要自定义它将是最好的方法。

DataTable dt = new DataTable();

最后我的网格需要看起来像这样:

            Mark    Jacob   Lauren   Sarah  
Math        50.6    70.8    21.9     81.7  
Science     21.8    19.4    61.1     65.2  
History     70.7    78.7    99.5     73.7  
English     80.1    11.1    12.1     65.1 

有人可以给我一个示例,说明如何获取ClassGrades的对象列表并动态创建类似于上述的数据表。 我希望在可能的情况下使用linq。另外,如果在sql中完全这样做是我喜欢的首选方式,但是一个例子会很好。

需要注意几点:

  • 主题只会是那些4。
  • 学生可以是随机数量,具体取决于课程中学生人数。
  • 对于班级中的每个学生,都会返回一行。

以下是我遇到困境的示例:

// retrieve object list
IList<ClassGrade> classGrades = ClassService.GetClassGrades(classId: 1);

// create datatable
DataTable dt = new DataTable();

// get list of students
var students = from s in classGrades
               select s.Student

// get list of subjects
IList<string> subjects = new List<string>() { "Math", "Science", "History", "English" };

// create columns
table.Columns.Add(subject, typeof(string));
foreach (var student in students)
{
    table.Columns.Add(student, typeof(double));
}

// create rows
foreach (var subject in subjects) 
{
    row = dt.NewRow();
    row[subject] = subject;

    foreach (var classGrade in classGrades)
    {
        // this is where I get stuck
        row[classGrade.Student] = 
    }
}

1 个答案:

答案 0 :(得分:1)

在LinqPad中测试过。请参阅附图以了解结果。

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;

namespace PivotDataTable
{
    class Program
    {
        public static object GetPropValue(object src, string propName)
        {
            return src.GetType().GetProperty(propName).GetValue(src, null);
        }

        static void Main()
        {
            // retrieve object list
            var classGrades = new List<ClassGrades>() {
                new ClassGrades() {Id=1, ClassId=1, Student="Mark", Math=50.6, Science=21.8, History=70.7, English=80.1},
                new ClassGrades() {Id=2, ClassId=1, Student="Jacob", Math=70.8, Science=19.4, History=78.7, English=11.1},
                new ClassGrades() {Id=3, ClassId=1, Student="Lauren", Math=21.9, Science=61.1, History=99.5, English=12.1},
                new ClassGrades() {Id=4, ClassId=1, Student="Sarah", Math=81.7, Science=65.2, History=73.7, English=65.1}
            };

            // create datatable
            DataTable dt = new DataTable();

            // get list of students
            var students = from s in classGrades
                select s.Student;

            // get list of subjects
            var subjects = new List<string>() { "Math", "Science", "History", "English" };

            // create columns
            dt.Columns.Add("subject", typeof(string));
            foreach (var student in students)
            {
                dt.Columns.Add(student, typeof(double));
            }

            // create rows
            foreach (var subject in subjects)
            {
                var row = dt.NewRow();
                row[0] = subject;

                foreach (var classGrade in classGrades)
                {
                    row[classGrade.Student] = Convert.ToDouble(GetPropValue(classGrade, subject));
                }

                // add row to data table
                dt.Rows.Add(row);
            }

            Console.Write("Press any key to continue . . . ");
            // to see the result in LinqPad: remark the ReadKey line, unremark the Dump line
            Console.ReadKey(true);
            //dt.Dump();
        }
    }

    class ClassGrades
    {
        public int Id { get; set; }
        public int ClassId { get; set; }
        public string Student { get; set; }
        public double Math { get; set; }
        public double Science { get; set; }
        public double History { get; set; }
        public double English { get; set; }
    }
}

enter image description here