C# 最后排序具有空值的事件日期

C# Ordering event dates with null values last

我正在使用 C# 编写课程列表,一门课程最多可以有 5 个 运行 日期。理想情况下,将选择未来今天之后的下一个日期,并在列表中相应地排序。

到目前为止我有一个课程列表,它获取下一个日期并显示它,但它首先显示所有没有日期的事件 (Null/Blank)。我试图先显示有下一个日期的课程,然后再显示没有日期的课程。

C#代码:

public ActionResult FilterList(string role = null, string category = null)
    {
        return View("~/Views/FilterList.cshtml", GetCourses(role, category));
    }

    [NonAction]
    public List<IEnumerable<Course>> GetCourses(string role = null, string category = null)
    {
        var collection = new List<IEnumerable<Course>>();
        var items = Sitecore.Context.Database.GetItem(SitecoreIDs.Pages.CourseRoot)
            .Children.Where(m => m.TemplateID == Course.TemplateID)
            .Select(m => (Course)m).ToList();

        var dates = new List<FilterDates>();
        items.ForEach(m => dates.Add(new FilterDates
        {
            Dates = new List<DateTime>{ m.Date1, m.Date2, m.Date3, m.Date4, m.Date5 },
            Name = m.Name
        }));

        dates.ForEach(m => m.Dates.RemoveAll(n => n == new DateTime(0001, 01, 01)));
        dates.ForEach(m => m.Dates.Sort((a, b) => a.CompareTo(b)));
        dates = dates.OrderBy(m => m.Dates.AsQueryable().FirstOrDefault(n => n - DateTime.Now >= TimeSpan.Zero)).ToList();
        var model = new List<Course>();
        dates.ForEach(m => model.Add(items.AsQueryable().FirstOrDefault(n => n.Name == m.Name)));

        if (!string.IsNullOrEmpty(role) || !string.IsNullOrEmpty(category))
        {
            var currentRole = Sitecore.Context.Database.GetItem(SitecoreIDs.Pages.CategoryRoot)
                .Children.AsQueryable().FirstOrDefault(m => m.Fields["Key"].Value == role);

            if (!string.IsNullOrEmpty(category))
            {
                var currentCategory = Sitecore.Context.Database.GetItem(SitecoreIDs.Pages.SeriesRoot)
                .Children.AsQueryable().FirstOrDefault(m => m.Fields["Key"].Value == category);

                model = model.Where(m => m.Series == currentCategory.Name).ToList();

                if (string.IsNullOrEmpty(role))
                {
                    collection.Add(model);
                }
            }

            if (!string.IsNullOrEmpty(role))
            {
                model = model.Where(m => m.InnerItem.Children.Where(n => n.Fields["Key"].Value == currentRole.Name).Any()).ToList();
                List<Course> required = new List<Course>(), recommended = new List<Course>(), refresh = new List<Course>();

                foreach (var item in model)
                {
                    foreach (Item inner in item.InnerItem.Children)
                    {
                        if (inner.Fields["Key"].Value == currentRole.Name)
                        {
                            switch (inner.Fields["Severity"].Value)
                            {
                                case "Required":
                                    required.Add(item);
                                    break;
                                case "Recommended":
                                    recommended.Add(item);
                                    break;
                                case "Refresh":
                                    refresh.Add(item);
                                    break;
                            }
                        }
                    }
                }

                collection.Add(required);
                collection.Add(recommended);
                collection.Add(refresh);
            }
        }
        else
        {
            collection.Add(model);
        }
        return collection;
    }

我尝试了不同的 orderbys,但似乎无法正确排序。任何帮助将不胜感激。

安迪

您发布的代码有一些额外的内容,这些内容似乎与您关于排序的问题无关。我忽略了这一点,只是解决了手头的问题:如何对课程进行排序,以便最接近未来日期的课程排在第一位。

我会创建一个小方法来 return 下一个未来日期或 DateTime.MaxValue 作为 "null" 值。

private DateTime GetNextFutureDate(Course course)
{
    var dates =
        new[] {course.Date1, course.Date2, course.Date3, course.Date4, course.Date5}.Where(d => d > DateTime.Now).ToArray();
    return dates.Length == 0 ? DateTime.MaxValue : dates[0];
}

然后在您的 GetCourses 方法中,您可以像这样使用它:

[NonAction]
public List<IEnumerable<Course>> GetCourses(string role = null, string category = null)
{
    var collection = new List<IEnumerable<Course>>();
    var model = Sitecore.Context.Database.GetItem(SitecoreIDs.Pages.CourseRoot)
        .Children.Where(m => m.TemplateID == Course.TemplateID)
        .Select(m => (Course)m).OrderBy(m => GetNextFutureDate(m));

    if (!string.IsNullOrEmpty(role) || !string.IsNullOrEmpty(category))
    // ... the rest of your code ...

    return collection;
}

您可能还想考虑使 GetNextFutureDate 成为课程 class 的成员或扩展方法 class。