views:

744

answers:

3

I'm trying to check if a date is null in linq and if it isn't check its a future date.

QuestionnaireRepo.FindAll(q => !q.ExpiredDate.HasValue || q.ExpiredDate >DateTime.Now).OrderByDescending(order => order.CreatedDate);

I need the second check to only apply if the first is true. I am using a single repository pattern and FindAll accepted a where clause

ANy ideas? There are lots of similar questions on here but not that give the answer, I'm very new to Linq as you may of guessed :)

Edit: I get the results I require now but it will be checking the > conditional on null values in some cases. Is this not a bad thing?

+1  A: 

Won't this work?

QuestionnaireRepo.FindAll(
    q => (q.ExpiredDate == null) || (q.ExpiredDate > DateTime.Now));
LukeH
I'm returning active entries :)
Andi
@SocialAddict: Can you clarify the exact criteria you require? Your question says "check if a date is not null ... and if it isn't check its a past date" which is exactly what my code does (and the code given in all the other answers so far). However, the example code in your question doesn't do that!
LukeH
Good point rewritten that, sorry :)
Andi
@SocialAddict: I've updated my answer following your edit, however my code is now pretty much the same as your own (which looks like it does exactly what you say it should be doing).
LukeH
just wasn't sure if i had to wrap the second condition so its only checks if its not null
Andi
@SocialAddict: The `||` operator short-circuits - that is, it only evaluates the second clause when the first clause is false. In your case the second condition will only be evaluated when the `ExpiredDate` property is not null.
LukeH
+1  A: 

If this is Linq-to-Sql or Linq-To-Entities then HasValue will not translate to a SQL Expression and you'll get an exception.

This should do it.

QuestionnaireRepo.FindAll(q => q.ExpiredDate != null && q.ExpiredDate <= DateTime.Now)
willbt
+1  A: 

There's a couple of ways you could do this, one nice way is using Pipes and Filters, but looking at how you're implementing the above, it doesn't look like you're using this pattern so won't go into it, but its worth googling.

With Pipes and Filters pattern you could do this:

        public static IQueryable<YourType> WithExpiryDate(this IQueryable<YourType> allMyTypes)
        {
            return allMyTypes.Where(f => f.ExpiredDate != null);
        }

        public static IQueryable<YourType> WhereExpiredDateBeforeThanNow(this IQueryable<YourType> allMyTypes)
        {
            return allMyTypes.Where(f => f.ExpiredDate <= DateTime.Now);
        }

And then just go: QuestionnaireRepo.FindAll().WithExpiryDate().WhereExpiredDateBeforeThanNow().SingleOrDefault();

You could also just say:

QuestionnaireRepo.FindAll(q => q.ExpiredDate != null && q.ExpiredDate <= DateTime.Now);

Hope this helps...

Richard