从对象列表创建反向数据表
Create inversed datatable from object list
我的 ClassGrades table 具有以下字段:
Id, ClassId, Student, Match, Science, History, English
我使用如下函数检索所有正确的行:
IList<ClassGrade> classGrades = ClassService.GetClassGrades(classId: 1);
此列表中的 ClassGrade 对象如下所示:
Id=1,ClassId=1,学生='Mark',数学=50.6,科学=21.8,历史=70.7,英语=80.1
Id=2,ClassId=1,学生='Jacob',数学=70.8,科学=19.4,历史=78.7,英语=11.1
Id=3,ClassId=1,学生='Lauren',数学=21.9,科学=61.1,历史=99.5,英语=12.1
Id=4,ClassId=1,学生='Sarah',数学=81.7,科学=65.2,历史=73.7,英语=65.1
我需要翻转这些结果,使学生成为列,带成绩的科目成为行,然后将其绑定到我页面上的网格。
我认为创建一个新数据 table 并根据需要对其进行自定义是执行此操作的最佳方法。
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 的对象列表并动态创建类似于上述内容的数据table。
我更愿意尽可能使用 linq。此外,如果在 sql 中完全执行此操作是首选方式,我也可以接受,但举个例子会很好。
有几点需要注意:
- 主题只会是那 4 个。
- 学生人数可以是任意数量,具体取决于 class 中有多少学生。
- 对于 class 中的每个学生,返回一行。
下面是我遇到问题的示例:
// 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] =
}
}
在 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; }
}
}
我的 ClassGrades table 具有以下字段:
Id, ClassId, Student, Match, Science, History, English
我使用如下函数检索所有正确的行:
IList<ClassGrade> classGrades = ClassService.GetClassGrades(classId: 1);
此列表中的 ClassGrade 对象如下所示:
Id=1,ClassId=1,学生='Mark',数学=50.6,科学=21.8,历史=70.7,英语=80.1
Id=2,ClassId=1,学生='Jacob',数学=70.8,科学=19.4,历史=78.7,英语=11.1
Id=3,ClassId=1,学生='Lauren',数学=21.9,科学=61.1,历史=99.5,英语=12.1
Id=4,ClassId=1,学生='Sarah',数学=81.7,科学=65.2,历史=73.7,英语=65.1
我需要翻转这些结果,使学生成为列,带成绩的科目成为行,然后将其绑定到我页面上的网格。 我认为创建一个新数据 table 并根据需要对其进行自定义是执行此操作的最佳方法。
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 的对象列表并动态创建类似于上述内容的数据table。 我更愿意尽可能使用 linq。此外,如果在 sql 中完全执行此操作是首选方式,我也可以接受,但举个例子会很好。
有几点需要注意:
- 主题只会是那 4 个。
- 学生人数可以是任意数量,具体取决于 class 中有多少学生。
- 对于 class 中的每个学生,返回一行。
下面是我遇到问题的示例:
// 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] =
}
}
在 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; }
}
}