我正在尝试按用户手动设置的发布日期订购列表。如果未设置发布日期,我想按创建日期(由系统自动设置)排序。
这是我到目前为止尝试过的方法,但是即使发布的日期值不等于其默认值,似乎该集合也仅按创建日期排序:
viewModel.News = model.Content.Children<NewsItem>().OrderBy(x => x.PublishDate == default(DateTime) ? x.CreateDate : x.PublishDate).ToList();
仅供参考。PublishDate和CreatedDate属性是只读的。
答案 0 :(得分:1)
如果发布日期相同,是否可以按创建日期排序?如果是,那么可以将这种方法与ThenBy一起使用:
viewModel.News = model.Content.Children<NewsItem>().OrderBy(x => x.PublishDate).ThenBy(x => x.CreateDate).ToList();
答案 1 :(得分:0)
您忘了告诉我们您的model.Content.Children<NewsItem>()
序列是IEnumerable
还是IQueryable
。
如果您不知道这意味着什么:是您的进程,那么它将进行枚举,还是另一个进程,例如数据库管理系统为您获取数据?
如果序列为IEnumerable
,我的建议是创建一个Compare类为您进行比较。这样做的好处是,如果将来您决定以其他方式订购,您的LINQ不会改变。缺点:这不适用于数据库(这就是为什么我问它是否可查询的原因)。 IEnumerable情况在结尾。
IQueryable最常用于要由另一个进程(例如数据库管理系统)执行查询的情况。因为它将由其他人执行,所以功能仅限于相当简单的功能。毕竟:您可能已经创建了VeryUsefulFunction()
,但是SQL不知道这一点。
如果未设置发布日期,我想按创建日期排序
因此,我们需要选择要提取OrderDate的位置:PublishedDate或CreatedDate。之后,您可以按OrderDate订购
var result = model.Content.Children<NewsItem>().Select(newsItem => new
{
OrderDate = newsItem.PublishedDate ?? newsItem.CreatedDate,
Item = newsItem,
})
.OrderBy(newsItem => newsItem.OrderDate)
// if desired, throw away the OrderDate:
.Select(newsItem => newsItem.Item)
几个LINQ到实体将不接受空合并运算符(??)。在这种情况下,您将在运行时遇到异常。如果是这种情况,则需要使用三元运算符(?:)
您也可以将IQueryable代码用作Enumerable。但是,在这种情况下,您将“早期新闻项”的概念与处理过程混合在一起,使它们的可读性,可测试性和可变性降低。例如,如果您需要一遍又一遍地订购新闻项目的概念,则必须复制粘贴此代码。此外,如果将来您想以不同的顺序(例如,按新闻项目的长度排序),则需要查找并重写所有对新闻项目进行排序的LINQ语句。
更好的办法是定义哪个新闻在另一个新闻之前。为此,您编写了一个实现IComparer<NewsItem>
的类。
class NewsItemComparer : IComparer<NewsItem>
{
public static readonly IComparer<NewsItem> Default = new NewsItemComparer();
private static readonly IComparer<DateTime> dateComparer = Comparer<DateTime>.Default;
public int Compare(NewsItem x, NewItem y)
{
// TODO: decide what to do if x or y NULL: exception? first? last?
return dateComparer.Compare(x.PublishedDate ?? x.CreatedDate,
y.PublishedDate ?? y.CreatedDate);
}
}
用法:
var result = model.Content.Children<NewsItem>()
.OrderBy(newsItem => newsItem, NewsItemComparer.Default);
这看起来比将比较代码放入查询中更加整洁。如果您决定以不同的方式进行比较,则此代码以及所有其他要比较NewsItems的代码都不会更改。实施各种比较方法甚至相当简单,例如按日期,按长度或按作者,...