使用DynamicProxies在List上排序

时间:2014-07-11 09:32:50

标签: c# asp.net-mvc linq

在控制器中,我有一个查询,其结果将显示在视图中。

这是查询结果模型的样子:

    public class Timesheet
    {
        [Key]
        public virtual int TimesheetId { get; set; }

        [Required]
        public virtual int TimesheetWeek { get; set; }

        [Required]
        public virtual DateTime TimesheetWeekStarts { get; set; }

        [Required]
        public virtual DateTime TimesheetWeekEnds { get; set; }

        [Required]
        public virtual string TimesheetOwner { get; set; }

        [Required]
        public virtual ICollection<TimesheetEntry> TimesheetEntries { get; set; }
    }

这是TimesheetEntry模型:

public class TimesheetEntry
{
    [Key]
    public virtual int EntryId { get; set; }

    [Required]
    public virtual DateTime EntryDate { get; set; }

    [Required]
    public virtual double TotalHours { get; set; }

    public Timesheet Timesheet { get; set; }

    [Display(Name = "Project number")]
    [ForeignKey("Project")]
    public virtual int ProjectId { get; set; }
    public virtual Project Project { get; set; }
}

查询将始终只返回一个Timesheet类,其中包含多个TimesheetEntries。 通常我希望条目的数量是确定的数字。让我们说在这种情况下它应该是56.所以如果

    TimesheetEntries.Count() != 56

我将手动向查询结果中添加其他条目,以确保条目数量符合要求。 完成后,我将按日期订购参赛作品。

    TimesheetEntries.OrderBy(x => x.EntryDate).OrderBy(x => x.Project);

一些伪代码显示让我遇到问题的过程:

public void PseudoCode()
    {
        const int REQUIRED_NUMBER_OF_ENTRIES = 45;

        //this will return only one instance of model due to .FirstOrDefault()
        var result = this.db.Timesheets.Where(x => x.TimesheetWeekStarts <= DateTime.Now).Select(x => x)
            .Where(x => x.TimesheetOwner == User.Identity.Name)
            .FirstOrDefault();

        if (result != null)
        {
            //if number of entries is not what I expect
            if(result.TimesheetEntries.Count() < REQUIRED_NUMBER_OF_ENTRIES)
            {
                //check how many to add
                int entriesMissing = REQUIRED_NUMBER_OF_ENTRIES - result.TimesheetEntries.Count();

                //add missing entries as empty entries
                for (int i = 0; i < entriesMissing; i++)
                {
                    result.TimesheetEntries.Add(
                        new TimesheetEntry
                        {
                            //to shorten this I am only adding DateTime.Now, normaly different times/dates would be added
                            EntryDate = DateTime.Now,
                            TotalHours = 8
                        });
                }
            }
        }

        result.TimesheetEntries.OrderBy(x => x.EntryDate).OrderBy(x => x.ProjectId);
    }

以下是排序结果:

Sorting result

所以列表首先包含有序的DynamicProxies,然后命令手动添加条目。

但顺序应该是:

  1. DynamicProxies.TimesheetEntry
  2. TimesheetEntry
  3. TimesheetEntry
  4. DynamicProxies.TimesheetEntry ......等等。
  5. 这是为什么?为什么订单结果以这种方式订购? 或者我这样做完全错了......

1 个答案:

答案 0 :(得分:0)

问题是OrderBy没有对集合进行排序,返回排序的IEnumerable。如果您希望集合反映OrderBy操作,则必须像这样分配回来:

result.TimesheetEntries = result.TimesheetEntries
                                .OrderBy(x => x.EntryDate)
                                .ThenBy(x => x.ProjectId)
                                .ToList();

编辑 - 另外,正如smartcaveman所指出的,如果你想按多列排序,你应该在第一个ThenBy之后使用OrderBy来进行所有后续排序。如果您不使用ThenBy(),则每个OrderBy()将继续在当前OrderBy字段上重新排序。