Linq中按语句分组的用法以按行显示数据

时间:2018-07-19 09:10:05

标签: asp.net-mvc linq linq-to-sql

我被困于每月显示学生出勤率视图。我打算使用linq实现它。 我想要的输出是类似

student ID | 1  |2  |3  |4  |5  |6  |7  |8  |9 |10 |................
1          | P  |P  |A  |L  |P  |A  |P  |L  |P |A  |................

我有两个桌子

学生桌

 public class StudentMeta
    {
        public int Student_ID { get; set; }
        public string Roll_No { get; set; }
        public string Name { get; set; }
        etc ......
}

和学生出勤表

  public partial class tbl_Students_Attandance
    {
        public int monthdays { get; set; }
    }



    public class StuAttandance
    {
        public int id { get; set; }
        public System.DateTime AttandanceDate { get; set; }
        public int StudentID { get; set; }
        public string Status { get; set; }
        public int ClassSectionId { get; set; }
    }

我将使用一个函数,通过使用Jquery从下拉列表中选择月份,我将通过一个月的天数

  public ActionResult ViewMonthlyAttandance(int monthDays, int classID)
    {
        ViewBag.ClassesList = new SelectList(db.tbl_Classes, "Id", "Class_Name");

      List<tbl_Students_Attandance> Stu_Attendence =  db.tbl_Students_Attandance.Where(x => x.ClassSectionId == classID).ToList();

        // here some "Group by" statment will be used to get my "P" or "A" Stu_Staus from db according to student_ID


        return View();
    }

我知道我的视图将是这样

<table>
    <thead>
        <tr>
            <th>Attendance Day</th>
            @foreach (var MD in Model.MonthDays)
            {
                <th>@MD</th>
            }

        </tr>
    <thead>
    <tbody>
        @foreach (var student in Model.Students)
        {
            <tr>
                <td>@student.Name</td>
                @foreach (var item in Model.Stu_Staus)
                {
                    <td>@item</td>
                }
            </tr>
        }
    </tbody>
}

我想知道如何将数据从控制器传递到视图,以及是否需要在视图中进行任何更改。

任何帮助将不胜感激。感谢你。

1 个答案:

答案 0 :(得分:0)

因此,您有一个StuAttendances序列,其中每个StuAttendance都属于使用外键的一个Student和一个ClassSection

每个StuAttendance都有一个属性AttendanceDate和一个Status,反映出AttendanceDate的出席情况。

现在给定classIdmonthId(月份从1..12开始编号),您需要一系列对象,其中每个对象都包含一个StudentId和一个{{1 }},其中此列表中的每个元素都包含该月该日期的学生状态以及该月的索引以及所请求的monthId

使用后者很难说,如果monthId = 7,则列表中的元素[14]是7月14日学生的出勤状态(quatorze juillet)

我遗漏了您的规格中的一些项目。

  • monthDays还不够,您还需要一年,以表明您想要的是2018年7月的所有日期,而不是2017年7月的日期。
  • 在您的数据库结构中,可能有一个学生缺席并在同一日期出现,或者有一段时间缺席同一天。
  • 在您的数据库结构中,我们也有可能在2018年7月14日没有学生的出勤状态。如果是这样,您最终的结果是什么?

首先,我们需要一系列需要出席的Datetime对象:

List

现在我们已经获得了最终结果所需的天数顺序,我们可以在int year = ... int month = ... DateTime startOfMonth = new DateTime(year, month, 1); DateTime startOfNextMonth = startOfMonth.AddMonths(+1); int daysInMonthCount = (int)((startOfNextMonth - startOfMonth).TotalDays()); IEnumerable<DateTime> daysToInvestigate = Enumerable.Range(0, daysInMonthCount) .Select(day => startOfMonth.AddDays(day)); 的这些天中吸引StuAttendances中所有classSectionid的学生:

daysToInvestigate

将所有学生按StudentId分组,在每个学生要求的月份内,您的出勤率:

int classSectionId = ...
var studentsInClassDuringMonth = StuAttandance
    .Where(studentAttendance => studentAttence.ClassSectionId = classSectionId
         && studentAttendance => daysToInvestigate.Contains(studentAttendance.AttendanceDate);

每个组都包含该月该班级一名学生的所有数据。

由于本月某些日期可能没有学生记录,所以不能说列表中的元素编号[4]包含第5天的状态。因此,最终结果中,我们需要日期和状态:

var attendancyPerStudent = studentsInClassDuringMonth.GroupBy(student => student.StudentId)

TODO:如果需要,请做一个大的LINQ语句。由于尚未执行任何查询,因此不要期望任何性能提高。但是,期望降低可读性,所以我不确定这是否明智。