I have a list of objects that contain a start/end date. I am trying to either find the current one if a current record exists, or failing that, the most recently expired one.
- Current is defined as a non null start date that is in the past and either a null end date (open ended) or and end date in the future.
- The most recently expired could be defined as having no current time period with a maximum end date. In theory, the time spans denoted by each object should never overlap so I’d expect maximum end date to be sufficient for most recently expired.
I was trying to follow this answer to a similar question, but I can’t seem to find the correct entry when there are other entries in the list that are future dated (ie. have a start/end date where both are in the future).
My attempt is as follows where a is start date, b is end date, c is an indicator for me to use while debugging, and d is used to define a list entry type. I am only interested in type 2.
[TestMethod]
public void TestRetrievalOfListElements()
{
var baseDate = DateTime.Now;
var list = new[]
{
new { a = new DateTime?(baseDate.AddDays(-90)),
b = new DateTime?(baseDate.AddDays(-60)), c = "LongExpired", d=1 },
new { a = new DateTime?(baseDate.AddDays(-190)),
b = new DateTime?(baseDate.AddDays(-160)), c = "LongestExpired", d=1 },
new { a = new DateTime?(baseDate.AddDays(-59)),
b = new DateTime?(baseDate.AddDays(+20)), c = "Current", d=1 },
new { a = new DateTime?(baseDate.AddDays(-159)),
b = new DateTime?(baseDate.AddDays(-91)), c = "LongerExpired", d=1 },
new { a = new DateTime?(baseDate.AddDays(-90)),
b = new DateTime?(baseDate.AddDays(-60)), c = "LongExpired", d=2 },
new { a = new DateTime?(baseDate.AddDays(-190)),
b = new DateTime?(baseDate.AddDays(-160)), c = "LongestExpired", d=2 },
new { a = new DateTime?(baseDate.AddDays(-59)),
b = new DateTime?(baseDate.AddDays(+20)), c = "Current", d=2 },
new { a = new DateTime?(baseDate.AddDays(-159)),
b = new DateTime?(baseDate.AddDays(-91)), c = "LongerExpired", d=2 },
new { a = new DateTime?(baseDate.AddDays(+21)),
b = new DateTime?(baseDate.AddDays(+60)), c = "Future", d=2 },
}.ToList();
// The following isn't really right either as it doesn't take into account
// whether d is of type 1 or 2 either. Not sure how to combine aggregates and
// other conditions ie MIN and of type 2
var oldestEntry = (from x in list
where x.a == list.Min(d => d.a) &&
x.d == 2
select x).FirstOrDefault();
Assert.IsTrue(oldestEntry.a == baseDate.AddDays(-190), "Expected oldest date to be 190 days earlier than today");
var latestEntryThatIsntInTheFuture =
(from x in list
from y in list.Where(z => z.d == 2 && z.a <= baseDate)
where x.a == list.Max(d => d.a) &&
x.d == 2
select x).FirstOrDefault();
Assert.IsTrue(latestEntryThatIsntInTheFuture.a == baseDate.AddDays(-59), "Expected latest date that isn't in the future to be 59 days earlier than today");
}
This might be what you’re looking for:
So you don’t need an aggregate in the query in my opinion.