0
votes

I've created a news-section in my website. Nothing new and working fine. Except now I wanna sort the news items by date. One problem is that the sorting dates are spread over multiple columns. I've created a newsdate field which isn't mandatory. When the newsdate column is empty the created date is used.

how do I sort my newsItems using both of these column

Example

newsitem1: newsdate = 3 aug 2012, createDate = 7 aug 2012

newsitem2: newsdate = emtpy, create date = 7 aug 2012

newsitem3: newsdate = 25 jul 2012, createDate 7 aug

Result (sorting order):

newsitem2, newsitem1, newsitem3

because all is created in Umbraco using a razorview-marco I see no option to manipulate the object so the sorting has to be done in a linq-query.

var nodes = @Model.AncestorOrSelf("Home").Children.Where("Visible").OrderBy(???)
3
Is it possible to create a new dynamic object within a Lambda or something like that? like: @var nodes = @Model.AncestorOrSelf("Home").Children.Where("Visible").OrderBy(new DateTime("newsdate"=='' ? DateTime.Parse("newsdate" : DateTime.Parse("createDate") "desc");Luuk Krijnen

3 Answers

0
votes

You can use a conditional expression in the order by : .OrderByDescending(t => t.NewsDate.HasValue ? t.NewsDate : t.CreationDate).ToList();

    public class News
    {
        public DateTime? NewsDate;
        public DateTime? CreationDate;
        public string Name;
        public News(string name, DateTime? newsDate, DateTime? creationDate) { this.Name = name; this.NewsDate = newsDate; this.CreationDate = creationDate; }
    }

    [TestMethod()]
    public void NewsTestOrderBy()
    {
        var news1 = new News("newsitem1", new DateTime(2012, 8, 3), new DateTime(2012, 8, 7));
        var news2 = new News("newsitem2", null, new DateTime(2012, 8, 7));
        var news3 = new News("newsitem3", new DateTime(2012, 7, 25), new DateTime(2012, 8, 7));

        var news = new List<News>() { news1, news2, news3 };
        var orderedNews = news.OrderByDescending(t => t.NewsDate.HasValue ? t.NewsDate : t.CreationDate).ToList();

        Assert.AreEqual(news2, orderedNews[0]);
        Assert.AreEqual(news1, orderedNews[1]);
        Assert.AreEqual(news3, orderedNews[2]);
    }
0
votes

When sorting anything mildly complex in Razor I have converted the results to a List then used a delagate. This was a special case that wasn't ideal, but gives you an idea of the syntax.

possibleListings.Sort(delegate(DynamicNode x, DynamicNode y)
{
  dynamic xNode = @Model.NodeById(x.Id);
  dynamic yNode = @Model.NodeById(y.Id);

  dynamic xListingLevel = @Model.NodeById(xNode.ListingType);
  dynamic yListingLevel = @Model.NodeById(yNode.ListingType);

  int xSort = xListingLevel.SortOrder;
  int ySort = yListingLevel.SortOrder;
  return xSort.CompareTo(ySort);
});

Hope that gets you on the right track.

0
votes

If your date fields are nullable DateTime values then this will work:

.OrderBy(x => x.newsdate ?? x.createDate)

If they are strings that are formatted in such a way they will sort properly then this will do the trick:

.OrderBy(x => !string.IsNullOrWhiteSpace(x.newsdate) ? x.newsdate : x.createDate)

If they are strings that have the values you shared in your example then you will need to convert them to DateTime instances to sort by like this:

.OrderBy(x => !string.IsNullOrWhiteSpace(x.newsdate) ? DateTime.Parse(x.newsdate) : DateTime.Parse(x.createDate))