直接上代码的吧
public class Grade
{
public int Id { get; set; }
public List<Student> Students { get; set; }
}
public class Student
{
public int Id { get; set; }
public int GradeId { get; set; }
public int Score { get; set; }
}
public static void Test()
{
List<Grade> mockGrades = new List<Grade>() {
new Grade() { Id = 1, Students = new List<Student>(){ new Student(){ Id=1, GradeId=1, Score=99}, new Student(){ Id=2, GradeId=1, Score=100}, new Student(){ Id=3, GradeId=1, Score=88}}},
new Grade() { Id = 2, Students = new List<Student>(){ new Student(){ Id=4, GradeId=2, Score=21}, new Student(){ Id=5, GradeId=2, Score=35}, new Student(){ Id=6, GradeId=2, Score=24}}},
new Grade() { Id = 3, Students = new List<Student>(){ new Student(){ Id=7, GradeId=3, Score=97}, new Student(){ Id=8, GradeId=3, Score=71}, new Student(){ Id=9, GradeId=3, Score=99}}},
new Grade() { Id = 4, Students = new List<Student>(){ new Student(){ Id=10, GradeId=4, Score=90}, new Student(){ Id=11, GradeId=4, Score=69}, new Student(){ Id=12, GradeId=4, Score=32}}},
new Grade() { Id = 5, Students = new List<Student>(){ new Student(){ Id=13, GradeId=5, Score=37}, new Student(){ Id=14, GradeId=5, Score=84}, new Student(){ Id=15, GradeId=5, Score=56}}}
};
var result = from i in mockGrades
//let i.Students = top 2 students
//这里应该怎么写?我希望获得年级的列表并且i.Students属性即每个年级的学生列表只保留前2名
select i;
}
另外,由于用在entity framework里,似乎没办法在linq语句里new Grade()...
求助啊
//方法一:
var result = mockGrades.Select(g =>
new
{
Id = g.Id,
Students = g.Students.Take(2)
});
//方法二:
var result2 = from i in mockGrades
select new
{
Id = i.Id,
Students = i.Students.Take(2)
};
这样写就可以了
用下面的代码输出:
Console.WriteLine("Result:");
foreach (var item in result)
{
Console.Write(item.Id + "\t");
foreach (var val in item.Students)
{
Console.Write(val.Id + "\t" + val.GradeId + "\t" + val.Score + "\t");
}
Console.WriteLine();
}
Console.WriteLine("\nResult2:");
foreach (var item in result2)
{
Console.Write(item.Id + "\t");
foreach (var val in item.Students)
{
Console.Write(val.Id + "\t" + val.GradeId + "\t" + val.Score + "\t");
}
Console.WriteLine();
}
呃,多谢。不过有点小问题
1.我希望最后返回的是grade对象而不是new的匿名对象
2.students可能要排下序 取scores最高的前2名
谢谢了
@wdwwtzy:
var result=new List<Grade>();
mockGrades.ForEach(g =>
{
result.Add(new Grade() {
Id = g.Id,
Students = g.Students.OrderByDescending(s => s.Score).Take(2).ToList()
});
});
//输出
foreach (var item in result)
{
Console.Write(item.Id + "\t");
foreach (var val in item.Students)
{
Console.Write(val.Id + "\t" + val.GradeId + "\t" + val.Score + "\t");
}
Console.WriteLine();
}
@天行健 自强不息: 呃,多谢。不过这里有个特定的条件,Grade是entity framework里的实体,他不允许new一个新的出来……似乎只可以select...
@wdwwtzy: 这里没有new啊:
var result=new List<Grade>();
mockGrades.ForEach(g =>
{
result.Add(new Grade() {
Id = g.Id,
Students = g.Students.OrderByDescending(s => s.Score).Take(2).ToList()
});
});
@天行健 自强不息:
这个就是啊,entity framework会报错....
result.Add(new Grade() {
@wdwwtzy: 晕啊,这个与EF没关系的,你是不是哪写的有问题啊,EF怎么会报错呢,报什么错
@天行健 自强不息: 嗯,我是稍微改了,因为如果按你刚才ForEach的写法,那么mockGrades就已经是从数据库读出来了,就是说已经把所有学生读出来,然后才操作list进行top 2的,那么我是希望可以在数据库里进行top 2的操作直接取出前2名。所以按理说可以写成这个样子
var result = from g in mockGrades
select new Grade(){
........
};
但是这样是会报错的,就是我刚才说的 不允许new
The entity or complex type 'Grade' cannot be constructed in a LINQ to Entities query.
@wdwwtzy: 你直接返回一个IQueryable类型,怎么会出错呢?
var result = (from g in mockGrades
select new
{
Grade = g.Id,
Students = (from s in g.Students
orderby
s.Score descending
select s).Take(2).ToList()
});
foreach (var item in result)
{
Console.WriteLine("班级:{0}", item.Grade);
foreach (var student in item.Students)
{
Console.WriteLine("\t学生号:{0},班级编号:{1},分数:{2}", student.Id, student.GradeId, student.Score);
}
}