I have been having a tough time getting an attendance table for a classroom to be displayed in an appropriate fashion. I have an Attendance table in my database that I can get to display quite easily with the data from just one classroom, but it displays in a way that looks like how it would look if you browsed to the attendance table directly in the database.
It is probably easier for me to explain by showing my work:
I have the following classes:
The actual classroom class, or Course:
public class Course
{
public int CourseID { get; set; }
public string Title { get; set; }
public int AttendanceDate { get; set;}
public virtual ICollection<Enrollment> Enrollments { get; set; } // allows Students to be enrolled in a Course
etc. . .
}
My Students:
public class Student
{
public int StudentID { get; set; }
public string Name { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; } // allows Student to be enrolled in a Course
etc. . .
}
The entity that ties the Students to the Courses:
public class Enrollment
{
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public virtual Course Course { get; set; }
public virtual Student Student { get; set; }
}
Attendance data:
public class Attendance
{
public int AttendanceID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public int AttendanceDay { get; set; } // used to set how many days people are supposed to attend this Course (each course has a different length, some are 10 day courses, some are 3, etc.)
public bool Present { get; set; } // absent or present (set to absent by default)
public virtual Course Course { get; set; }
public virtual Student Student { get; set; }
}
The flow of my project has Instructors creating a Course for Students to sign up. When a Student signs up for a Course, all the necessary Attendance data is input into the Attendance database table with default values (absent every day):
for (int i = 0; i < course.AttendingDays; i++)
{
Attendance newAttendance = new Attendance
{
CourseID = course.CourseID,
StudentID = thisStudent.StudentID,
AttendanceDay = i + 1,
Present = false
};
db.Attendance.Add(newAttendance);
db.Save();
}
So I have a database table with a bunch of attendance data and I cannot get it to display correctly on the screen, sorted similar to this:
Attendance Day 1 | 2 | 3 | 4 | 5 |
Student1 absent absent absent absent absent
Student2 absent absent absent absent absent
Student3 absent absent absent absent absent
Hopefully you can read that. . . I assume it is a pretty standard layout for an attendance table.
I have tried sorting the data with Group By:
var model = from s in db.Attendance
where s.CourseID == 4
group s.AttendanceDay by s.StudentID into t
select new
{
StudentID = t.Key,
Days = t.OrderBy(x => x)
};
return View(model);
Which returns an IEnumerable of anonymous type (If I understand correctly), but I cannot seem to get this data to do anything. If I use 'simpler' table generators (and don't try to Group By the AttendanceDay number) I get the attendance table data just fine, but it is sorted just like it is when you view the actual database table for Attendance, not very useful if you want an Instructor to read and edit the information.
I am thinking I need an appropriate ViewModel to adjust the incoming attendance data in the IEnumerable of anonymous type format, followed by a view that appropriately displays that ViewModel. . . but I am not sure how I would handle that process.
Any help would be appreciated. Thank you.
Update:
I am beginning to think I need to take advantage of a "cross-tab report" / "pivoting" and use something like this: http://linqlib.codeplex.com/wikipage?title=Pivot&referringTitle=Home
Any pointers?
Update 2:
Almost completely solved using the below accepted answer, and here is my current controller:
// Generates list of Attendances specifically for current Course
var attendanceItems = db.Attendance.Where(s => s.CourseID == id);
List<Attendance> attendanceItemsList = attendanceItems.ToList();
// End of generating list of Attendances
// CURRENT PROBLEM AREA - INCOMPLETE
var student = attendanceItemsList.Select(a => a.Student).Distinct()/*.OrderBy(a => a)*/; // This works for adding one student, Cannot use OrderBy in its current state - how can I properly order by name? (right now it will order by id I believe)
List<Student> StudentList = student.ToList();;
//
// Generates list of AttendingDays specifically for current Course
Course course = db.Courses.FirstOrDefault(p => p.CourseID == id);
List<int> attDayList = new List<int>();
for (int i = 0; i < course.AttendingDays; i++)
{
attDayList.Add(i + 1);
};
// End of generating list of AttendingDays
AttendanceReportViewModel model = new AttendanceReportViewModel
{
AttendanceDays = attDayList,
Students = StudentList,
Attendances = attendanceItemsList,
};
return View(model);