【问题标题】:How to perform a query using LINQ that must make one column distinct but includes all information of another column如何使用 LINQ 执行查询,该查询必须使一列不同但包含另一列的所有信息
【发布时间】:2017-09-13 13:53:15
【问题描述】:

我目前正在为使用 LINQ 从填充了以下内容的数据库获取信息的课程分配作业:

..学生名..|..班级..|..GPA..|.......课程..|..课程编号..|..FinalGrade..|..CSCIGPA..
......“D,卡拉”......|......SR......|......3.8......|......CSCI4220......|...... .....4220…………|…………A…………|…………3.9…… ...
......“D,卡拉”......|......SR......|......3.8......|......CSCI3110......|...... .....3110........|........A........|........3.9.. ....
....“R,思科”.....|....JR.....|...3.1...|...CSCI3010...|........ ...3030........|........B........|........3.4.... ..
....“R,思科”.....|....JR.....|...3.1...|...CSCI2070...|........ ...2070........|........C........|........3.4.... ..
....“R,思科”.....|....JR.....|...3.1...|...CSCI3030...|........ ...3030........|........B........|........3.4.... ..
....“A,巴里”......|....FR.....|...4.0...|...CSCI1010...|.... ....1010........|........A..........|........4.0... ...
....“A,巴里”......|....FR.....|...4.0...|...CSCI2010...|.... ....2010........|........A..........|........4.0... ...
....“问,奥利弗”.....|....SO....|...2.7...|...CSCI2020...|.... ..2010........|........C........|........2.8...... .
....“问,奥利弗”.....|....SO....|...2.7...|...CSCI2020...|.... ..2010........|........C........|........2.8...... .
....“问,奥利弗......|....SO....|...2.7...|...CSCI2030...|......... ..2030........|........C........|........2.8...... .
......“H,罗伊”......|....SO....|...3.8...|...CSCI2020...|...... .....2020............|........A.............|........3.7. .....

我没有包含所有列,但这是一个很好的示例。鉴于此输入,查询应返回按 GPA(从大到小)排序,然后按 CSCIGPA(从大到小)排序的每个班级(FR、SO、JR、Senior)的学生列表。此外,每个要显示的学生都应该有一个连接的“课程”和“最终成绩”,并且每个连接的课程和最终成绩也应该包含在列表中。例如,显示“A, Barry”的记录是:

“A,巴里”,FR,4.0,CSCI1010A CSCI2010A,4.0

注意:形成列 CourseNumber 的单个课程编号“1010 和 2010”不是输出的一部分。

我最大的问题是弄清楚如何将连接的课程和最终成绩纳入单个学生行(当我执行 Distinct() 时,它取消了除第一个课程和成绩之外的所有不同课程和成绩)。这是我写的一些代码,但我承认它不是很好,可能对这个问题没有帮助,因为我已经描述了它。

//method to iterate over all students within student table public IEnumerable<Student> GetAllStudents() { var myquery = databaseEDM.Students .OrderBy(x => x.Class).ThenByDescending(x => x.GPA).ThenByDescending(x => x.CSCIGPA) .ToList().Distinct(); return myquery; }

在此分配之前,我从未真正对数据库或查询做过任何事情,因此非常感谢任何帮助。如果我需要提供更多信息以获得正确答案,请告诉我。谢谢。

其他说明:这只是一个简单的控制台应用程序,它从数据库获取信息以输出。

【问题讨论】:

  • 提供的数据是非规范化的。因此,显而易见的问题是,如果“A,Barry”至少有一门课程的 GPA、CSCIGPA 或最终成绩不同,该怎么办?

标签: c# sql database linq


【解决方案1】:

您的代码需要一个 Student 类,而您在发布的代码中没有 Student 类。在下面的代码中,我希望结果位于数据表中(您可以从数据适配器中获取)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("StudentName", typeof(string));
            dt.Columns.Add("Class", typeof(string));
            dt.Columns.Add("GPA", typeof(decimal));
            dt.Columns.Add("Course", typeof(string));
            dt.Columns.Add("CourseNumber", typeof(int));
            dt.Columns.Add("FinalGrade", typeof(string));
            dt.Columns.Add("CSCIGPA", typeof(decimal));

            dt.Rows.Add(new object[] {"D, Kara","SR",3.8,"CSCI4220",4220,"A",3.9});
            dt.Rows.Add(new object[] {"D, Kara","SR",3.8,"CSCI3110",3110,"A",3.9});
            dt.Rows.Add(new object[] {"R, Cisco","JR",3.1,"CSCI3010",3030,"B",3.4});
            dt.Rows.Add(new object[] {"R, Cisco","JR",3.1,"CSCI2070",2070,"C",3.4});
            dt.Rows.Add(new object[] {"R, Cisco","JR",3.1,"CSCI3030",3030,"B",3.4});
            dt.Rows.Add(new object[] {"A, Barry","FR",4.0,"CSCI1010",1010,"A",4.0});
            dt.Rows.Add(new object[] {"A, Barry","FR",4.0,"CSCI2010",2010,"A",4.0});
            dt.Rows.Add(new object[] {"Q, Oliver","SO",2.7,"CSCI2020",2010,"C",2.8});
            dt.Rows.Add(new object[] {"Q, Oliver","SO",2.7,"CSCI2020",2010,"C",2.8});
            dt.Rows.Add(new object[] {"Q, Oliver","SO",2.7,"CSCI2030",2030,"C",2.8});
            dt.Rows.Add(new object[] { "H, Roy", "SO", 3.8, "CSCI2020", 2020, "A", 3.7 });

            var myquery = dt.AsEnumerable()
               .OrderBy(x => x.Field<string>("Class")).ThenByDescending(x => x.Field<decimal>("GPA")).ThenByDescending(x => x.Field<decimal>("CSCIGPA")).ToList();
        }
    }
}

【讨论】:

  • 这不会为每个(班级,学生)对输出一行
【解决方案2】:

这是您的工作示例:

        public IEnumerable<Student> GetAllStudents()
        {
            var myquery = databaseEDM.Students
                .GroupBy(x => new { x.StudentName, x.Class })
                .Select(s => new
                {
                    StudentName = s.Key.StudentName,
                    Class = s.Key.Class,
                    GPA = s.Average(g => g.GPA),
                    Courses = string.Join(" ", s.Select(c => c.Course + c.FinalGrade)),
                    CSCIGPA = s.Average(cs => cs.CSCIGPA)
                })
                .OrderBy(x => x.Class)
                .ThenByDescending(x => x.GPA)
                .ThenByDescending(x => x.CSCIGPA)
                .ToList()
                .Distinct();
            return myquery;
        }

我做了什么?

我按StudentNameClass 将学生分组。

然后我只选择了您在示例中请求的属性。

然后我为每个组平均GPA,因为。

然后我加入了Course 加上FinalGrade 的那个组,因为你想要一个值。

最后,我为该组创建了平均CSCIGPA

希望我能正确理解您的问题。您的数据格式不是最好的,但此查询应该会有所帮助。

【讨论】:

  • 为什么要平均? OP 没有说明平均 GPACSCIGPA
  • @P. Kouvarakis 如果学生 A 的第一门课程的 GPA 为 3.5,另一门课程的 GPA 为 4.0,则 Barry。如果我们想放入单个记录,我们必须使用哪些数据?也许我没有正确理解这个问题!
  • 是的,那是我的问题,但原始海报没有指定使用哪一个,或者使用平均值或其他什么。所以这个问题需要澄清(你的答案也需要调整)
  • @P. Kouvarakis 你对数据结构的看法是完全正确的。我的假设是他需要平均数据。如果不是,那么这个解释无法解决这个问题。他需要更具体地说明结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多