如何使用LINQ(c#)连接两个集合并将集合转换为实体

时间:2011-12-04 22:45:54

标签: c# linq join pivot transpose

我有以下课程:

public class Student
{
    public string StudentID { get; set; }
    public string StudentName { get; set; }
}
public class Marks
{
    public string StudentID { get; set; }
    public string SubjectName { get; set; }
    public string Score { get; set; }
} 

填充集合:

Collection<Student> objStudentCollection = new Collection<Student>();
Student student = new Student();
student.StudentID = "104517";
student.StudentName = "John";
objStudentCollection.Add(student);

student = new Student();
student.StudentID = "104520";
student.StudentName = "Stella";
objStudentCollection.Add(student);

Collection<Marks> objMarkCollection = new Collection<Marks>();
Marks marks = new Marks();
marks.StudentID = "104517";
marks.SubjectName = "English";
marks.Score = "85";
objMarkCollection.Add(marks);

marks = new Marks();
marks.StudentID = "104517";
marks.SubjectName = "Science";
marks.Score = "60";
objMarkCollection.Add(marks);


marks = new Marks();
marks.StudentID = "104517";
marks.SubjectName = "Mathematics";
marks.Score = "75";
objMarkCollection.Add(marks);


marks = new Marks();
marks.StudentID = "104517";
marks.SubjectName = "Optional 1";
marks.Score = "75";
objMarkCollection.Add(marks);


marks = new Marks();
marks.StudentID = "104520";
marks.SubjectName = "French";
marks.Score = "54";
objMarkCollection.Add(marks);

marks = new Marks();
marks.StudentID = "104520";
marks.SubjectName = "Science";
marks.Score = "60";
objMarkCollection.Add(marks);


marks = new Marks();
marks.StudentID = "104520";
marks.SubjectName = "Mathematics";
marks.Score = "75";
objMarkCollection.Add(marks);


marks = new Marks();
marks.StudentID = "104520";
marks.SubjectName = "Optional 1";
marks.Score = "50";
objMarkCollection.Add(marks);

我想将GridView中的上述集合绑定为:

  

StudentID |学生名称|英语|法语|数学|科学|可选1 |总

1 个答案:

答案 0 :(得分:1)

我认为您需要使用GroupJoin方法来获取您所追求的内容。 如果主题列表固定而不会改变,你可以这样做:

<击>

<击>
var q = 
  objStudentCollection
  .GroupJoin(
    objMarkCollection,
    stu => stu.StudentID,
    mark => mark.StudentID,
    (stu, mark) =>
        new
        {
            student.StudentID,
            student.StudentName,
            English = mark.Where(m => m.SubjectName == "English").Sum(m => Convert.ToInt32(m.Score)),
            French  = mark.Where(m => m.SubjectName == "French").Sum(m => Convert.ToInt32(m.Score)),
            Mathematics  = mark.Where(m => m.SubjectName == "Mathematics").Sum(m => Convert.ToInt32(m.Score)),
            Science   = mark.Where(m => m.SubjectName == "Science").Sum(m => Convert.ToInt32(m.Score)),
            Optional1  = mark.Where(m => m.SubjectName == "Optional 1").Sum(m => Convert.ToInt32(m.Score)),
            Total = mark.Sum(m => Convert.ToInt32(m.Score)),
        })

这不是世界上最漂亮的代码,但它会为您提供一个匿名类型,每行包含您要求的数据。如果每个主题只有一个标记,则可以将Sum替换为SingleOrDefault

<击>

var subjects = 
    objMarkCollection
    .Select(mark => mark.SubjectName)
    .Distinct()
    .Dump();

var q =  
    objStudentCollection 
    .GroupJoin( 
        objMarkCollection, 
        stu => stu.StudentID, 
        mark => mark.StudentID, 
        (stu, mark) => 
            new 
            { 
                student.StudentID, 
                student.StudentName, 
                Marks = 
                    from s in subjects
                    join m in mark on s equals m.SubjectName into outer
                    from o in outer.DefaultIfEmpty()
                    select new
                    {
                        SubjectName = s,
                        Score = (o == null) ? 0 : Convert.ToInt32(o.Score),
                    },
                Total = mark.Sum(m => Convert.ToInt32(m.Score)), 
            }) 
    .Dump();

第二个解决方案将为您创建一个匿名类型,每个学生和一个标记集合,包括每个主题(学生未参加的标记将得到0分)。