【问题标题】:Usage of Group by Statement in Linq to show data in rows在 Linq 中使用 Group by 语句以行显示数据
【发布时间】:2018-07-19 09:10:05
【问题描述】:

我因按月显示学生出勤视图而陷入困境。我正在尝试使用 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>
}

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

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

【问题讨论】:

  • 明智地获取数据 Student 并不是很复杂,尽管很大程度上取决于您获取数据的方式。您当然可以按学生分组,然后分组值应包含List,其中包含每天和出勤数据。有关如何存储数据的更多信息会有所帮助。现在你如何展示它是你的选择,与 Linq 无关
  • 谢谢@MrinalKamboj.. 但是我将如何在标题行下显示缺席的日子?
  • 我的意思是 jquery 函数将传递天数,然后我将使用 for 循环遍历该数字。并将其显示到标题。我将如何在确切日期(数字)下方显示我的状态@MrinalKamboj
  • 您在错误的类别下发布了您的问题,一旦您将数据作为包含日期和出勤信息的列表,使用GroupBy 很简单,那么更多关于JQuery 将如何处理它用正确的标签和相关信息发布问题
  • 如果我不使用 jquery @MrinalKamboj.. 有什么其他方法可以使用 linq 实现它吗?

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


【解决方案1】:

所以你有一个StuAttendances 序列,其中每个StuAttendance 恰好属于一个Student 和一个使用外键的ClassSection

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

现在给定一个 classId 和一个 monthId(从 1..12 开始编号),您需要一个对象序列,其中每个对象都包含一个 StudentId 和一个 List,其中此列表中的每个元素包含学生在本月日期的状态,以及具有请求的月份 ID 的月份索引

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

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

  • monthDays 不够,还需要一年,表示您想要 2018 年 7 月的所有日期。而不是 2017 年 7 月的日期
  • 在您的数据库结构中,可以让学生在同一日期缺勤和在场,或者在同一日期多次缺勤。
  • 在您的数据库结构中,也有可能我们在 2018 年 7 月 14 日没有任何学生的出勤状态。如果是这种情况,您希望最终结果是什么?

首先,我们需要一系列 Datetime 对象,我们希望在这些对象上参与:

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

现在我们已经得到了最终结果中想要的天数序列,我们可以在daysToInvestigate 的天数中获取classSectionid 中的所有StuAttendances 学生:

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

按 StudentId 将它们全部分组,并且每个学生在请求的月份内都有出勤率:

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

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

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

var result = attendancyPerStudent.Select(group => new
{
     StudentId = group.Key,
     Attendancy = group.Select(attendancy => new
     {
         Date = attendancy.AttendanceDate,
         Status = attendany.Status,
     });
})

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

【讨论】:

  • 非常感谢@Harald Coppoolse.. 它为我指明了正确的方向。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多