0

I'm getting strange results using trying to do a simple query against a date column using Linq and EF Core.

If I run the query using a date from a list of DateTime I get no results. If I substitute DateTime.Now and add a negative number of days so that if matches the date in the list of DateTimes then the query returns results as expected.

So what is the difference between DateTime.Now and another DateTime object?

In practice, why would this work (rewinding now by 30 days in the first example gives the same date as datesToCheck[0] in the second):

 var reports = from r 
               in db.DailyReports
                    .Where(r => r.UserId.Equals(currentuser.Identity.Name) 
                             && r.Date > DateTime.Now.AddDays(-30)) 
               select r;

But not this:

var reports = from r 
              in db.DailyReports
                   .Where(r => r.UserId.Equals(currentuser.Identity.Name) 
                            && r.Date > datesToCheck[0]) 
              select r;

The database is SQL Server 2017, the column is a non-nullable smalldatetime

The datesToCheck list is generated thus:

var datesToCheck = new List<DateTime>();

var startDate =  DateTime.Now;
//get Monday date three weeks ago
if (DateTime.Now.DayOfWeek != DayOfWeek.Monday)
{
    while (startDate.DayOfWeek != DayOfWeek.Monday)
        {
            startDate = startDate.AddDays(-1);
        }
}

startDate = startDate.AddDays(-21);
while (startDate < DateTime.Now)
{
    if (startDate.DayOfWeek != DayOfWeek.Saturday || startDate.DayOfWeek != DayOfWeek.Sunday)
    {
        datesToCheck.Add(startDate);
        startDate = startDate.AddDays(1);
    }       
}   
3
  • Doesnt make sense, can you show us datesToCheck[0] declaration and values? Commented Apr 5, 2017 at 16:15
  • No problem Juan Carlos - I've added it to the question Commented Apr 5, 2017 at 16:19
  • Doesn't make sense, both predicates will be evaluated in memory (first because of AddDays function, second because of array/list indexer). As soon as datesToCheck[0] contains DateTime.Now.AddDays(-30), both queries should return one and the same result. Commented Apr 5, 2017 at 16:52

2 Answers 2

2

The same behavior exists in EF6 and, as far as I know, all versions of EF. Basically, the compiler isn't clever enough to decide if datesToCheck[0] should be evaluated or converted to SQL. The query will work if you store the value in a variable and then use the variable in the LINQ query. See also: Why can't we use arrays in Entity Framework queries?

Sign up to request clarification or add additional context in comments.

Comments

0

You probably have some datatype issue, Try:

DateTime datesToCheck = DateTime.Now.AddDays(-30);
var reports = from r 
              in db.DailyReports
                   .Where(r => r.UserId.Equals(currentuser.Identity.Name) 
                            && r.Date > datesToCheck ) 
              select r;

2 Comments

Thanks Juan Carlos - that works the same as placing DateTime.Now.AddDays(-30) inside the query. It's only when I try to use a value from the list of DateTime that it fails. Even if I create a new DateTime variable and assign the value from the list to it it still returns no results.
As I said, the problem is with the datesToCheck[0] variable did you debug the value? I still checking your code, but dont see anything yet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.