Reputation: 9388
Not sure why its complaining about this error, but when comparing time stamps to DateTime.now I get a object reference error. Here is the simple code.
public class EmailTempKey
{
public string Id { get; set; }
public DateTime LastUpdated { get; set; }
public bool ShouldBeDisposed { get; set; }
}
//Linq Query to see if its been past 8 min
var emails = session.Query<EmailTempKey>().Where(x => DateTime.Now > x.LastUpdated.AddMinutes(8)).ToList();
If I remove the where clause it works, but obviously I need that. Thanks for any help
Upvotes: 0
Views: 1515
Reputation: 13558
I think this would fix it
Depending if the datetime LastUpdated may be null, choose one of the solutions below
May be null:
//Linq Query to see if its been past 8 min
var emails = session.Query<EmailTempKey>().Where(x => x.LastUpdated == DateTime.MinValue || (DateTime.Now > x.LastUpdated.AddMinutes(8)).ToList();
May not be null:
//Linq Query to see if its been past 8 min
var emails = session.Query<EmailTempKey>().Where(x => x.LastUpdated != DateTime.MinValue && (DateTime.Now > x.LastUpdated.AddMinutes(8)).ToList();
Upvotes: 0
Reputation: 241693
When you express a LINQ query, keep in mind that RavenDB has to translate that to Lucene before executing it. Therefore, you need to be thinking about how a particular field is being compared to the value you are passing in. You wrote:
Where(x => DateTime.Now > x.LastUpdated.AddMinutes(8))
Your LastUpdated
field would need to be mutated for each record in order to resolve this query. This isn't something that Lucene or Raven can do. Just because you can express it in LINQ does not mean that it is valid for Raven. Instead, you could write:
Where(x => x.LastUpdated < DateTime.Now.AddMinutes(-8))
This is the algebraic equivalent to the query you specified, and should work, but there are still some problems.
You probably want an inclusive comparison, either <=
or >=
The query will return items older than 8 minutes ago. I could be wrong, but I think you meant you wanted items newer than 8 minutes old, in which case you would flip the comparison:
Where(x => x.LastUpdated >= DateTime.Now.AddMinutes(-8))
Using DateTime.Now
can be problematic. You are imposing the local time zone settings of the server onto your data. If your time zone uses daylight savings time, then twice a year you will get the wrong results from your query when your clocks transition. Even if you don't follow daylight savings time, you have a problem if you ever want to move your data somewhere else (like to the cloud, or an ISP). You should also read my post: The Case Against DateTime.Now. You should be storing your dates as UTC, or you can use DateTimeOffset
- which works beautifully in RavenDB.
Perhaps you didn't realize, but RavenDB already keeps a Last-Modified
value on every document in its metadata. You could use your own field if you want to, but why store it twice? You can query based on metadata with the Lucene syntax:
var results = session.Advanced.LuceneQuery<EmailTempKey>()
.WhereGreaterThan("@metadata.Last-Modified",
DateTime.UtcNow.AddMinutes(8));
If you want to stick with the LINQ syntax, you will need to define a static index instead.
Upvotes: 3