ExceptionLimeCat
ExceptionLimeCat

Reputation: 6400

LINQ FirstOrDefault Returing more than 1 result

I'm trying to get the oldest record from a list using LINQ. I just want the TOP record essentially. It looked like FirstOrDefault method does the trick but upon testing my query in LINQPad. I'm getting a dataset not just one record..

Anyone know how to just return 1 record?

List<Event> schedule = new List<Event>()
{
    new Event(){eventID = 776734, eventName = "HGP", eventStartDate = Convert.ToDateTime("2011-09-01"), eventEndDate = Convert.ToDateTime("2011-09-18"), runningHours = 0.0000, runningStartStops = 0.0000},
    new Event(){eventID = 776735, eventName = "CI", eventStartDate = Convert.ToDateTime("2012-10-01"), eventEndDate = Convert.ToDateTime("2012-10-11"), runningHours = 0.0000, runningStartStops = 0.0000},
    new Event(){eventID = 776736, eventName = "HGP", eventStartDate = Convert.ToDateTime("2014-03-01"), eventEndDate = Convert.ToDateTime("2014-03-18"), runningHours = 0.0000, runningStartStops = 0.0000},
    new Event(){eventID = 779236, eventName = "CI", eventStartDate = Convert.ToDateTime("2015-11-10"), eventEndDate = Convert.ToDateTime("2015-11-23"), runningHours = 2774.3300, runningStartStops = 111.3400},
    new Event(){eventID = 779364, eventName = "MA", eventStartDate = Convert.ToDateTime("2017-03-11"), eventEndDate = Convert.ToDateTime("2017-04-04"), runningHours = 4176.0200, runningStartStops = 104.3400},
    new Event(){eventID = 779365, eventName = "CI", eventStartDate = Convert.ToDateTime("2019-04-05"), eventEndDate = Convert.ToDateTime("2019-04-13"), runningHours = 8054.6700, runningStartStops = 232.5100},
    new Event(){eventID = 779366, eventName = "HGP", eventStartDate = Convert.ToDateTime("2021-04-02"), eventEndDate = Convert.ToDateTime("2021-04-19"), runningHours = 13473.1300, runningStartStops = 389.3500},
    new Event(){eventID = 779367, eventName = "CI", eventStartDate = Convert.ToDateTime("2023-03-31"), eventEndDate = Convert.ToDateTime("2023-04-08"), runningHours = 18930.8900, runningStartStops = 520.0200}
};

var q = from evt in schedule
         where "MA,HGP".Contains(evt.eventName)
         group evt by evt.eventID into x
         select x.OrderByDescending(t => t.eventStartDate).FirstOrDefault();

//LINQPad method to show results     
q.Dump();

Upvotes: 3

Views: 1241

Answers (2)

ocuenca
ocuenca

Reputation: 39326

You need to close your query in parenthesis:

var q = (from evt in schedule
         where "MA,HGP".Contains(evt.eventName)
         group evt by evt.eventID into x
         select x.OrderByDescending(t => t.eventStartDate)).FirstOrDefault();

Your query is selecting the first element of each sorted group.

Update

But why do you need to group if you just are looking the newest event? Try changing the group by to an order by:

var q = (from evt in schedule
         where "MA,HGP".Contains(evt.eventName)
         order evt by evt.eventStartDate 
         select x).FirstOrDefault();

Or, as @TimSchmelter recommended in his comment, order your elements before group them.

Upvotes: 6

Ki_Netic
Ki_Netic

Reputation: 132

Just to explain the why to the already posted answers.

The OrderByDescending returns an IOrderedEnumerable and you are calling the FirstOrDefault() method on that return value. Enclosing the query in "()" like stated octavioccl's answer will call the FirstOrDefault() method on the query result instead.

Upvotes: 1

Related Questions