NHibernate 3.0: Pas de FirstOrDefault () avec QueryOver?

Je joue avec FluentNHibernate et NH 3.0, en utilisant le fournisseur LINQ et la nouvelle syntaxe QueryOver.

Maintenant avec QueryOver je veux obtenir un élément (appelé résultat) avec une valeur d'horodatage aussi près que possible à une valeur donnée, mais pas plus:

 Result precedingOrMatchingResult = Session.QueryOver<Result>().
        Where(r => r.TimeStamp < timeStamp).
        OrderBy(r => r.TimeStamp).Desc.                
        FirstOrDefault(); //get the preceding or matching result, if there is any

Maintenant, Intellisense me dit qu'il n'existe pas de méthode FirstOrDefault(). Je pourrais, bien sûr, énumérer ma requête ordonnée, puis utiliser LINQ pour obtenir mon article. Mais cela chargerait tous les éléments en mémoire premier.

Y a-t-il une alternative à FirstOrDefault(), ou Ai-je compris quelque chose de complètement faux?

27
demandé sur Marcel 2010-12-29 16:23:49

4 réponses

NH 3 a un fournisseur LINQ intégré (les requêtes sont traduites en interne en HQL / SQL). Vous devez ajouter le NHibernate.Espace de noms Linq puis:

Result precedingOrMatchingResult = Session.Query<Result>().
    Where(r => r.TimeStamp < timeStamp).
    OrderByDescending(r => r.TimeStamp).
    FirstOrDefault();
11
répondu Diego Mijelshon 2010-12-29 22:19:43

J'ai maintenant découvert que je pouvais utiliser la méthode D'extension Take () sur L'instance IQueryOver, et seulement l'énumération à une liste, comme ceci:

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
35
répondu Marcel 2010-12-29 14:04:07
Result precedingOrMatchingResult = Session.QueryOver<Result>()
                                          .Where(r => r.TimeStamp < timeStamp)
                                          .OrderBy(r => r.TimeStamp).Desc
                                          .SingleOrDefault();
22
répondu RRR 2011-09-10 03:35:45

Essayez

Result precedingOrMatchingResult = Session.QueryOver<Result>().
        Where(r => r.TimeStamp < timeStamp).
        OrderBy(r => r.TimeStamp).Desc.
        SetFetchSize(1).
        UniqueResult();

UniqueResult retournera une seule valeur, ou null si aucune valeur n'est trouvée, ce qui est un peu ce que First ou Default fait.

Définir la taille D'extraction à 1 peut ou non être nécessaire, je le testerais avec un profileur.

10
répondu tom.dietrich 2010-12-29 13:44:09