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

发布于 2024-12-19 07:00:08 字数 1925 浏览 2 评论 0原文

我有以下类:

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 中绑定上述集合以显示如下:

学生ID |学生姓名 |英语 |法语 |数学|科学|可选 1 |总计

I have the following classes:

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; }
} 

Populating the collection:

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);

I would like to bind the above collections in GridView to display like:

StudentID | StudentName | English | French | Mathematics | Science | Optional 1 | Total

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

極樂鬼 2024-12-26 07:00:08

我认为您需要利用 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 分)。

I think you need to utilise the GroupJoin method to get what you're after.
You could do it like this if the list of subjects if fixed and not going to change:

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)),
        })

It's not the prettiest code in the world, but it will give you an anonymous type with each row containing data you asked for. You could replace Sum with SingleOrDefault if there is only ever one mark per subject.

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();

This 2nd solution will create you an anonymous type with each student and a collection of marks including each subject (those the student has not take will have a 0 score).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文