Question

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

Maintenant, avec QueryOver Je veux obtenir un élément (résultat appelé) avec une valeur d'horodatage aussi proche que possible d'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'y a pas une telle chose comme méthode de 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 d'abord.

Y at-il une alternative à FirstOrDefault(), ou ai-je compris quelque chose de complètement tort?

Était-ce utile?

La solution

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

Result precedingOrMatchingResult = Session.Query<Result>().
    Where(r => r.TimeStamp < timeStamp).
    OrderByDescending(r => r.TimeStamp).
    FirstOrDefault();

Autres conseils

J'ai trouvé que je pouvais utiliser le Take () méthode d'extension sur l'instance IQueryOver, et seule la liste enumerate à une, comme suit:

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();

Essayez

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

uniqueResult retourne une valeur unique, ou NULL si aucune valeur est trouvée, ce qui est un peu ce qui ne fonctionne d'abord ou par défaut.

Réglage de la taille Fetch 1 peut ou non être nécessaire, je voudrais vérifier que avec un profileur.

SetFetchSize(1) est nécessaire. Si votre requête renvoie LINQ plus d'un résultat, il lancera une exception en utilisant NHibernate UniqueResult(), car il attend qu'un seul résultat soit renvoyé par la requête.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top