I am playing with FluentNHibernate and NH 3.0, using the LINQ provider and the new QueryOver syntax.
Now with QueryOver I want to get an item (called result) with a timestamp value as close as possible to a given value, but not greater:
Result precedingOrMatchingResult = Session.QueryOver<Result>().
Where(r => r.TimeSt开发者_C百科amp < timeStamp).
OrderBy(r => r.TimeStamp).Desc.
FirstOrDefault(); //get the preceding or matching result, if there is any
Now, Intellisense tells me that there is no such thing as a FirstOrDefault() method. I could, of course, enumerate my ordered query, and then use LINQ to get my item. But this would load all items into memory first.
Is there an alternative to FirstOrDefault(), or have I understood something completely wrong?
I have now found out that I could use the Take() extension method on the IQueryOver instance, and only the enumerate to a list, like so:
Result precedingOrMatchingResult = Session.QueryOver<Result>().
Where(r => r.TimeStamp < timeStamp).
OrderBy(r => r.TimeStamp).Desc.
Take(1).List(). //enumerate only on element of the sequence!
FirstOrDefault(); //get the preceding or matching result, if there is any
Result precedingOrMatchingResult = Session.QueryOver<Result>()
.Where(r => r.TimeStamp < timeStamp)
.OrderBy(r => r.TimeStamp).Desc
.SingleOrDefault();
NH 3 has an integrated LINQ provider (queries are translated internally to HQL/SQL). You have to add the NHibernate.Linq namespace and then:
Result precedingOrMatchingResult = Session.Query<Result>().
Where(r => r.TimeStamp < timeStamp).
OrderByDescending(r => r.TimeStamp).
FirstOrDefault();
Try
Result precedingOrMatchingResult = Session.QueryOver<Result>().
Where(r => r.TimeStamp < timeStamp).
OrderBy(r => r.TimeStamp).Desc.
SetFetchSize(1).
UniqueResult();
UniqueResult will return a single value, or null if no value is found, which is kinda what First or Default does.
Setting the Fetch Size to 1 may or may not be required, I'd test that with a profiler.
SetFetchSize(1) is required. If your LINQ query returns more than one result, it will throw an NHibernate exception using UniqueResult(), as it is only expecting one result to be returned from the query.
加载中,请稍侯......
精彩评论