Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq to Entity Birthday Comparison

Tags:

c#

linq

I have the requirement to create a query using Linq to Entities where the birthday must fall within 2 days ago and the next 30 days.

The following returns nothing:

DateTime twoDaysAgo = DateTime.Now.AddDays(-2);
int twoDaysAgoDay = twoDaysAgo.Day;
int twoDaysAgoMonth = twoDaysAgo.Month;
DateTime MonthAway = DateTime.Now.AddDays(30);
int monthAwayDay = MonthAway.Day;
int monthAwayMonth = MonthAway.Month;
var bdays = from p in db.Staffs where EntityFunctions.TruncateTime(p.BirthDate) > EntityFunctions.TruncateTime(twoDaysAgo) &&
                     EntityFunctions.TruncateTime(p.BirthDate) < EntityFunctions.TruncateTime(MonthAway)
                    orderby p.BirthDate select p;
return bdays;

The problem I'm having is that I need something where if the birthday falls from 11/3 to 12/5, it should return it. The reason it fails because the birthdays include the Year. However, when I use something like:

p.BirthDate.Value.Month 

I receive the error that this isn't support with Linq to Entities. Any assistance would be appreciated.

like image 718
user2903500 Avatar asked Nov 05 '13 16:11

user2903500


1 Answers

Year-wrapping independent solution:

void Main()
{
    var birthdays = new List<DateTime>();
    birthdays.Add(new DateTime(2013, 11, 08));
    birthdays.Add(new DateTime(2012, 05, 05));
    birthdays.Add(new DateTime(2014, 05, 05));
    birthdays.Add(new DateTime(2005, 11, 08));
    birthdays.Add(new DateTime(2004, 12, 31));


    foreach(var date in birthdays.Where(x => x.IsWithinRange(twoDaysAgo, MonthAway))){
      Console.WriteLine(date);
    }           
}

public static class Extensions {
    public static bool IsWithinRange(this DateTime @this, DateTime lower, DateTime upper){
        if(lower.DayOfYear > upper.DayOfYear){
            return (@this.DayOfYear > lower.DayOfYear || @this.DayOfYear < upper.DayOfYear);
        } 

        return (@this.DayOfYear > lower.DayOfYear && @this.DayOfYear < upper.DayOfYear);
    }
}

Output with

DateTime twoDaysAgo = DateTime.Now.AddDays(-2);
DateTime MonthAway = DateTime.Now.AddDays(30);

8/11/2013 0:00:00
8/11/2005 0:00:00

Output with

DateTime twoDaysAgo = new DateTime(2012, 12, 25);
DateTime MonthAway = new DateTime(2013, 01, 05);

31/12/2004 0:00:00
like image 141
Jeroen Vannevel Avatar answered Oct 02 '22 13:10

Jeroen Vannevel