如何为具有适当布局的教室展示制作“考勤表”?

时间:2012-05-10 15:12:46

标签: asp.net-mvc entity-framework razor viewmodel

我一直很难找到以适当的方式展示教室的考勤表。我的数据库中有一个考勤表,我可以很容易地使用来自一个教室的数据进行显示,但它的显示方式与您直接在数据库中直接浏览考勤表的方式相同。 / p>

通过展示我的作品,我可能更容易解释:

我有以下课程:

实际的课堂课程,或课程:

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

我的学生:

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

将学生与课程联系起来的实体:

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

出勤数据:

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

我的项目流程有教师为学生创建课程注册。当学生报名参加课程时,所有必要的考勤数据都会输入到考勤数据库表中,并带有默认值(每天不存在):

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

所以我有一个包含大量考勤数据的数据库表,我无法在屏幕上正确显示,排序类似于:

出席第1天| 2 | 3 | 4 | 5 |

学生1缺席缺席缺席缺席

学生2缺席缺席缺席缺席

学生3在缺席缺席的情况下缺席

希望你能读懂。 。 。我认为这是一个非常标准的考勤表布局。

我尝试使用分组依据对数据进行排序:

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

返回IEnumerable的匿名类型(如果我理解正确的话),但我似乎无法获取此数据做任何事情。如果我使用'更简单'的表生成器(并且不尝试按出勤日数分组),我可以很好地获得考勤表数据,但它的排序方式与查看实际数据库表时的排序方式一样,不是很好如果您希望教师阅读和编辑信息,则非常有用。

我想我需要一个合适的ViewModel来调整IEnumerable匿名类型格式的传入考勤数据,然后是一个适当显示ViewModel的视图。 。 。但我不确定如何处理这个过程。

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

更新

我开始认为我需要利用“交叉表报告”/“旋转”并使用以下内容:http://linqlib.codeplex.com/wikipage?title=Pivot&referringTitle=Home

任何指针?

更新2:

使用下面接受的答案几乎完全解决了,这是我现在的控制器:

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

2 个答案:

答案 0 :(得分:3)

我认为您应该考虑创建一个包含日期列表,学生列表和出勤条目列表的ViewModel,然后在出勤日期间简单地遍历学生及其中,然后显示出勤记录为每个人。

所以ViewModel看起来像这样:


public class AttendanceReportViewModel
{
    public List<int> AttendanceDays { get; set; }
    public List<Student> Students { get; set; }
    public List<Attendance> Attendances { get; set; }

    public string IsPresent(Student student, int attendanceDay)
    {
         return Attendances.Single(a => a.StudentID == student.ID && a.AttendanceDay == attendanceDay).Present ? "present" : "absent";
    }
}

确保按照您希望的方式对所有项目进行排序,但这是简单的OrderBy内容。另外,请确保仅加载相关课程的出勤率,并将任何课程数据添加到您要显示的viewModel。

然后在你的视图中迭代如下:


<table>
    <thead>
        <tr>
            <th>Attendance Day</th>
            @foreach (var attendanceDay in Model.AttendanceDays)
            {
                <th>@attendanceDay</th>
            }
        </tr>
    <thead>
    <tbody>
        @foreach (var student in Model.Students)
        {
            <tr>
                <td>@student.Name</td>
                @foreach (var attendanceDay in Model.AttendanceDays)
                {
                    <td>@Model.IsPresent(student, attendanceDay)</td>
                }
            </tr>
        }
    </tbody>
}

只是为你一起打破了这个,所以甚至不确定我的确切代码是否编译,但我希望它能给你一个很好的起点。显然应该应用表格的某些样式等。

编辑1:

要将数据加载到视图模型中,您可以在控制器中执行此操作(从技术上讲,这应该在存储库中,甚至可以在服务层中)


var viewModel = new AttendanceReportViewModel();

viewModel.AttendanceDays = db.Attendance.Select(a => a.AttendanceDay).Distinct().OrderBy(a => a)
...

我还应该注意到,当然您也只能将考勤数据加载到视图模型中,然后从ViewModel中根据此数据生成AttendanceDays和Students属性。我现在避免这样做,因为你很可能也想要学生数据。

编辑2

对于学生而言,您希望所有学生都能在课堂上注册,但由于您已经预先确定了所有日期的出勤数据,因此您可以这样做:


var viewModel = new AttendanceReportViewModel();

viewModel.AttendanceDays = db.Attendance.Select(a => a.AttendanceDay).Distinct().OrderBy(a => a);
viewModel.Students = db.Attendance.Select(a => a.Student).Distinct().OrderBy(s => s.Name);

或者,您可以从注册表中加载此信息,如下所示:


viewModel.Students = db.Enrollment.Where(e => e.CourseID == courseID).Select(e => e.Student).OrderBy(s => s.Name);

请注意,我认为在注册表中课程和学生ID之间存在唯一约束,而课程ID是您为其生成出勤报告的内容。此外,您的注册表中的课程已映射到上面的学生,我认为这是不正确的。

答案 1 :(得分:0)

from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import pandas as pd
import urllib.request
import os

def wait_till_load(driver,class_name,by_elem):
    try:
        WebDriverWait(driver, 60).until(EC.presence_of_element_located((by_elem, class_name)))
    except TimeoutException:
        print("Time Out Exception")
        # df.to_excel(name + '/' + name + '.xlsx')
        exit()

df = pd.DataFrame(columns=['S.no','Category','BrandName','ItemTitle','Color','Size','Price','ImageUrl'])

search_item = int(input("1.MEN'S WEAR \n2.WOMEN'S WEARS \n3.THINGS AND THINGS \nEnter the category you want to search : "))
limit = int(input('Enter the maximum no.of records : '))
name = ''

# if search_item==1:
#     os.mkdir('MENS_WEAR')
#     name = 'MENS_WEAR'
# elif search_item == 2:
#     os.mkdir('WOMENS_WEAR')
#     name = 'WOMENS_WEAR'
# elif search_item == 3:
#     os.mkdir('THINGS')
#     name = 'THINGS'

url="https://www.ssense.com/ja-jp"

# language conversion in chrome

myoptions = webdriver.ChromeOptions()
prefs = {
  "translate_whitelists": {"ja":"en"},
  "translate":{"enabled":"true"}
}
myoptions.add_experimental_option("prefs", prefs)
driver=webdriver.Chrome(ChromeDriverManager().install(),options=myoptions)

driver.get(url)
if search_item==1:
    try:
        element= WebDriverWait(driver,10).until(
            EC.presence_of_element_located((By.LINK_TEXT,"MENSWEAR"))
        )
        element.click()
    except:
        driver.quit()
    # link =driver.find_element_by_link_text("MENSWEAR")
    # link.click()
elif search_item == 2:
    link = driver.find_element_by_link_text("WOMEN'S WEAR")
    link.click()
elif search_item == 3:
    link = driver.find_element_by_link_text("THINGS AND THINGS")
    link.click()


try:
    element= WebDriverWait(driver,10).until(
        EC.presence_of_element_located((By.CLASS_NAME,"plp-products__row"))
    )
    items = driver.find_elements_by_class_name('plp-products__column')
    itemsinpage=len(items)
    print(itemsinpage)
    items[0].find_element_by_class_name('plp-products__product-tile').click()
    WebDriverWait(driver,10).until(
        EC.presence_of_element_located((By.CSS_SELECTOR, "s-column.pdp-header"))
    )
  
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.CLASS_NAME, "s-row"))
    )
  
    brand = driver.find_element_by_class_name('s-row'). \
        find_element_by_css_selector('pdp-product-title__brand.s-text.s-text--uppercase'). \
        find_element_by_css_selector('a'). \
        find_element_by_css_selector('font'). \
        find_element_by_css_selector('font').text
    # details['BrandName'] = brand
    print(brand)

except:
    driver.quit()