星期几向后显示(星期六、星期五、星期四、星期三等),我不明白为什么

Days of the Week are being displayed backwords (Sat, fri, thru, wed, etc) and I can't figure out why

在我的项目中,我通过 LINQ to Entities 用数据填充一个复杂的 ViewModel,然后使用该数据构建一个 table,它将为用户显示每日时间表。我似乎在正确地获取数据,因为当我打印当天的工作小时数时,它们是正确的,但问题是打印的日期是错误的,它们被向后显示。

这是模型:

public class TimesheetWeeklyTableVM
{
    public int TimesheetHeaderID { get; set; }
    public DateTime WeekEndingDate { get; set; }
    public decimal TotalWeekHours { get; set; }

    public List<TimesheetDailyVM> DaysOfWeek { get; set; }

    public TimesheetWeeklyTableVM()
    {
        DaysOfWeek = new List<TimesheetDailyVM>();

        foreach (DayOfWeek dayOfWeek in Enum.GetValues(typeof(DayOfWeek)))
        {
            DaysOfWeek.Add(new TimesheetDailyVM()
            {
                DayOfWeek = dayOfWeek
            });
        }
    }
}

public class TimesheetDailyVM
{
    public DayOfWeek DayOfWeek { get; set; }

    public double TotalHours
    {
        get
        {
            return TimeSpan.FromSeconds(Tasks.Sum(p => (p.EndDateTime - p.StartDateTime).TotalSeconds)).TotalHours;
        }
    }

    public IEnumerable<TimesheetDailyHoursVM> Tasks { get; set; }

    public TimesheetDailyVM()
    {
        Tasks = new List<TimesheetDailyHoursVM>();
    }
}

public class TimesheetDailyHoursVM
{
    public int TimesheetID { get; set; }
    public DateTime StartDateTime { get; set; }
    public DateTime EndDateTime { get; set; }
    public string ProjectCode { get; set; }
    public string ProjectDescription { get; set; }
    public string TaskCode { get; set; }
    public string TaskDescription { get; set; }
}

以及用于填充该模型的代码:

var weekEndingDate = TimesheetHelper.GetWeekEndingDate(date);
var employeeID = UserHelper.GetUserID(User.Identity.Name);

using (var db = new JobSightDbContext())
{
    var model = db.TimesheetHeaders
                    .Where(timesheetHeader => timesheetHeader.WeekEndingDate == weekEndingDate && timesheetHeader.EmployeeID == employeeID)
                    .Select(timesheetHeader => new TimesheetWeeklyTableVM()
                    {
                        WeekEndingDate = weekEndingDate,
                        TimesheetHeaderID = timesheetHeader.ID,
                        TotalWeekHours = timesheetHeader.TotalHours
                    }).FirstOrDefault();

    var headerID = model.TimesheetHeaderID;

    var timeRecords = db.Timesheets
                        .Where(timesheet => timesheet.TimesheetHeaderID == headerID)
                        .ToList()
                        .GroupBy(timesheet => timesheet.StartDateTime.DayOfWeek);

    foreach (var record in timeRecords)
    {
        model.DaysOfWeek[(int)record.Key].Tasks = record.Select(x => new TimesheetDailyHoursVM()
        {
            TimesheetID = x.ID,
            StartDateTime = x.StartDateTime,
            EndDateTime = x.EndDateTime,
            ProjectCode = x.ProjectCode,
            TaskCode = x.TaskCode
        });
    }

    return PartialView(model);
}

以及显示它的代码:

@model TimesheetWeeklyTableVM

<table border="1">
    <thead>
        <tr>
            <th>
                Total Hours: <br />
                @Model.TotalWeekHours
            </th>
            @foreach (var day in Model.DaysOfWeek)
            {
                <th>
                    @Model.WeekEndingDate.AddDays(-(int)day.DayOfWeek).ToString("ddd MM/dd/yy")
                    <br />@day.TotalHours Hours Worked
                </th>
            }
        </tr>
    </thead>

    <tbody>
    </tbody>
</table>

我尝试将 .OrderBy(timesheet => timesheet.StartDateTime.DayOfWeek); 添加到填充 timeRecordsLINQ 查询,但这并没有影响任何东西。我错过了什么所以 table 将显示 Sun, Mon, Tue, Wed, Thr, Fri, Sat 中的日期?

这取决于您的 DaysOfWeek 系列的订购顺序。根据 high to lowlow to high 值打印日期。

@Model.WeekEndingDate.AddDays(-(int)day.DayOfWeek).ToString("ddd MM/dd/yy")

根据当前输出,您的 DaysOfWeek 列表似乎是按升序排列的。将其更改为降序,您将获得所需的结果。

 @foreach (var day in Model.DaysOfWeek.Cast<int>().OrderByDescending(x => x))

更新- 您的实体设计未正确对齐。要解决同步问题,请不要在 TimesheetWeeklyTableVM 构造函数中初始化 DaysOfWeek 列表。 DayOfWeek 可以从 TimesheetDailyHoursVM class 属性 StartDateTime 获取。只需 StartDateTime.DayOfWeek 即可为您提供星期几。 假设您的 StartDateTime 和 EndDateTime 涵盖一天。 TimesheetDailyVM的属性DayOfWeek可以这样初始化:

public DayOfWeek DayOfWeek 
{ 
 get {  
       return Tasks.First().StartDateTime.DayOfWeek; 
     }
 }

看起来你只需要订购你的 DaysOfWeek 你可以在你的视图 Model.DaysOfWeek 或你在这里进行交互后进行 foreach (DayOfWeek dayOfWeek in Enum.GetValues(typeof(DayOfWeek)))

问题是你的

@Model.WeekEndingDate.AddDays(-(int)day.DayOfWeek).ToString("ddd MM/dd/yy")

视图中的代码行。您有一个集合,其 DayOfWeek 属性 的范围从 0(星期日)到 6(星期六),并假设 WeekEndingDate 是 5 月 14 日(这个日期的最后一天)周),然后第 1 次迭代转换为

 WeekEndingDate.AddDays(-0) // results in 14th May

并且第二次迭代转换为

WeekEndingDate.AddDays(-1) // results in 13th May

等您需要将视图代码更改为

WeekEndingDate.AddDays(((int)day.DayOfWeek) - 6).ToString("ddd MM/dd/yy");

以便第一次迭代转换为

WeekEndingDate.AddDays(-6) // results in 8th May

以便第二次迭代转换为

WeekEndingDate.AddDays(-5) // results in 9th May

附带说明:我会考虑向您的 TimesheetWeeklyTableVM 构造函数添加一个参数

public TimesheetWeeklyTableVM(DateTime weekEnding)
{
    DaysOfWeek = new List<TimesheetDailyVM>();
    DateTime startDate = weekEnding.AddDays(-6);
    for(int i = 0; i < 6; i++)
    {
        DaysOfWeek.Add(new TimesheetDailyVM()
        {
            Date = startDate.AddDays(i)
        };
    }
}

并在您的 TimesheetDailyVM 模型中,将 public DayOfWeek DayOfWeek { get; set; } 替换为

[DisplayFormat(DataFormatString = "{0:ddd MM/dd/yy}")]
public DateTime Date{ get; set; }

并在您的第一个查询中使用

.Select(timesheetHeader => new TimesheetWeeklyTableVM(weekEndingDate)

然后在视图中,您可以使用

@foreach (var day in Model.DaysOfWeek)
{
    <th>
       @Html.DisplayFor(m => day.Date)
       <br />@day.TotalHours Hours Worked
    </th>
}

您还可以为小时添加 DisplayFormat 属性

[DisplayFormat(DataFormatString = "{0:0} HoursWorked")] // adjust if you want decimal places
public double TotalHours
{
   .....

并在视图中使用 @Html.DisplayFor(m => day.TotalHours)