这是我的班级:
public class Students
{
public String StudentName
public int CountActivities
public List<Activities> lstActivities = new List<Activities>();
}
public class Activities
{
public String ActivityName
public int ActivityScore
}
我想创建一个查询,显示学生名称为行,并将ActivityName显示为数据网格中的列。如果某项活动是由学生完成的,请在相应的行中显示该分数。细胞。我们知道活动列表的数量从1到X不等,但从不超过X.我希望CountActivities成为学生姓名旁边的第二列。第3列以后由学生参加的各种ActivityName标记。
如何创建查询以在数据网格中显示我想要的内容?我知道我必须创建一个导致List的查询。然后我可以将datagrid的源设置为List(我认为)。我的麻烦是理解如何制定查询以我刚才描述的格式呈现信息。
抱歉,我之前没有添加此部分:
List<Students> lstHighSchool = new List<Students>();
var Query = lstHighSchool ( *no clue*).ToList():
//from here I can hopefully assign List to datagrid's source.
答案 0 :(得分:1)
在Linq中这将是困难的(并且是静态的) - 我会创建一个循环遍历活动的DataTable,如果它们不存在则创建列。
伪码:
DataTable dt
add column Name
add column CountActivities
foreach(student)
{
add row
row[Name] = student.Name
row[CountActivities] = student.CountActivities
foreach(activity)
{
if(! (dt contains column (activity.ActivityName)))
add column (activity.ActivityName)
row[activity.ActivityName] = ActivityScore
}
}
答案 1 :(得分:1)
我认为您的问题 具有挑战性,所以我一直在努力实现目标。不确定它是否是您想要的,它需要清理一下以使其更通用。
我的想法是构建一个linq扩展来提供您请求的结构。我正在将数据移动到元组中,其中Item1是包含StudentName的字符串,而Item2是具有足够所有不同活动名称行的ActivityScores列表。分数正确添加到与我从学生列表中创建的已排序的不同列表匹配的col中,以便为每个活动分数获得正确的col。
然后我将结果打印到调试窗口。结果对我的样本是正确的,但可能存在一些错误。无论如何,这是一个开始:)
Another path could be just to build a List<string[]> in place of the
Tuple<string, List<int>>, and everything is converted to string for display.
欢迎任何建议。
这是:
using System;
using System.Collections.Generic;
using System.Linq;
namespace SO
{
class Program
{
static void Main(string[] args)
{
// Create Students List
var students = new List<Student>()
{
new Student
{
FirstName = "Paul",
LastName = "Smith",
ActivityList = new List<Activity>() {
new Activity
{
ActivityName = "Math", ActivityScore = 90
},
new Activity
{
ActivityName = "Biology", ActivityScore = 92
},
new Activity
{
ActivityName = "C#", ActivityScore = 93
}
}
},
new Student
{
FirstName = "Mary",
LastName = "Jones",
ActivityList = new List<Activity>() {
new Activity
{
ActivityName = "Linq", ActivityScore = 95
},
new Activity
{
ActivityName = "Phyics", ActivityScore = 99
},
new Activity
{
ActivityName = "C#", ActivityScore = 99
}
}
},
new Student
{
FirstName = "Slick",
LastName = "Willy",
ActivityList = new List<Activity>() {
new Activity
{
ActivityName = "Wine", ActivityScore = 90
},
new Activity
{
ActivityName = "Women", ActivityScore = 99
},
new Activity
{
ActivityName = "Politics", ActivityScore = 85
}
}
}
};
// Created a sorted list of activity Names
var activities = (from s in students from a in s.ActivityList select (a.ActivityName)).Distinct().ToList();
activities.Sort();
// Create a Tuple of <Name,Activities>
var grid = students.DataGrid(activities);
// Print Header
System.Diagnostics.Debug.Write(string.Format("{0,-12}", "Name"));
foreach (var item in activities)
{
System.Diagnostics.Debug.Write(string.Format("{0,12}",item));
}
System.Diagnostics.Debug.WriteLine("");
// Print Rows
foreach (var t in grid)
{
System.Diagnostics.Debug.Write(string.Format("{0,-12}", t.Item1));
foreach (var s in t.Item2)
{
System.Diagnostics.Debug.Write(string.Format("{0,12}", s));
}
System.Diagnostics.Debug.WriteLine("");
}
// Done
}
}
public class Student
{
public String FirstName { get; set; }
public String LastName { get; set; }
public List<Activity> ActivityList { get; set; }
}
public class Activity
{
public String ActivityName { get; set; }
public int ActivityScore { get; set; }
}
public static class LinqExt2
{
public static IEnumerable<Tuple<string, System.Collections.Generic.List<int>>> DataGrid<T>(this IEnumerable<T> source, IEnumerable<string> columnList)
{
using (var iterator = source.GetEnumerator())
{
// A List of Tuples in the format <string, List<int>>
var results = new List<Tuple<string, List<int>>>();
// each Student
while (iterator.MoveNext())
{
var a = iterator.Current as Student;
if (a == null)
continue;
// initalize all cols to 0;
var columnValues = columnList.Select(v => 0).ToList();
// each Activity
foreach (var item in a.ActivityList)
{
var name = item.ActivityName;
var i = 0;
foreach (var activity in columnList)
{
if (name.Equals(activity))
{
columnValues[i] = item.ActivityScore;
break;
}
i++;
}
}
results.Add(Tuple.Create(a.FirstName, columnValues));
}
return results;
}
}
}
}
<强>结果
强>
姓名生物学C#Linq数学Phyics政治葡萄酒女性
保罗92 93 0 90 0 0 0 0
玛丽0 99 95 0 99 0 0 0
光滑0 0 0 0 0 85 90 99
答案 2 :(得分:0)
您要做的事情称为“数据透视表”。
在LINQ中不可行。见(How to build pivot table through linq using c#)
请在此处查看其他选项:Pivot logic LINQ on DataTable