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。
我正在使用 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。