12
votes

NHibernate 3 paging et déterminer le nombre total de lignes

J'ai lu quelque part (je ne peux pas remettre où et comment) que NHibernate 3 permet de déterminer le nombre total d'enregistrements tandis que l'exécution d'une requête paginé (dans une base de données). Est-ce bon?

J'ai ce code: P>

Total = (int) Session.CreateCriteria<X>()
.SetProjection(Projections.RowCount())
.FutureValue<Int32>().Value;

var query = (from e in Session.Query<X>() select e).AsQueryable();

return query.Skip((Page - 1) * PageSize).Take(PageSize).ToList();


0 commentaires

3 Réponses :


2
votes

Je ne pense pas que NHibernate "réalise" la signification de toute requête qu'elle effectue, déterminez donc le nombre total de lignes n'est pas standard interrogé.

Le moyen le plus efficace d'obtenir le nombre de lignes est avec des contrats à terme ou une imultiquicité (pour obtenir tous les résultats en un tour de la base de données)

NHibernate-Futures


1 commentaires

J'ai ajouté quelque chose voir PS. Est-ce ce que vous faites référence et cette requête serait-elle exécutée dans un DB Trans? Merci.



25
votes

Votre solution potentielle sera traitée dans une transaction, mais sera deux appels à DB. Si vous ne devez avoir qu'un seul appel de DB, vous devez utiliser une requête à la multiquetière / future comme suggéré par des pairs. Pour plus d'informations sur la future syntaxe, consultez cet article: http://ayende.com/blog/ 3979 / NHibernate-Futures .

Voici quelques façons d'accomplir votre scénario ... P> Queryover (appels à 2 dB): em> xxx pré>

avec un ensemble d'échantillons de 100 Organismes et interrogation pour les organismes 11-20, voici les deux requêtes envoyées à la DB: P>

SELECT TOP (@p0) Id0_0_, Title0_0_ FROM (SELECT this_.Id as Id0_0_, this_.Title as Title0_0_, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM Organism this_) as query WHERE query.__hibernate_sort_row > @p1 ORDER BY query.__hibernate_sort_row;SELECT count(this_.Id) as y0_ FROM Organism this_;;@p0 = 10 [Type: Int32 (0)], @p1 = 10 [Type: Int32 (0)]


1 commentaires

Il convient probablement de noter que si les deux résultat dans une seule requête sont entraînés par des optimisations spécifiques à la dialecte. Par exemple sur SQLite Deux requêtes sont émises, mais le comportement est le même (tous les futures exécutés à la fois dans le moins de requêtes que possible)



4
votes

Je n'ai pas assez de réputation pour commenter la solution de CodeProgression ci-dessus ... mais le bon appel de DB utilisant Queryover W / Future est le suivant:

var query = session.QueryOver<Organism>()
    .Skip((Page - 1) * PageSize)
    .Take(PageSize)
    .Future<Organism>();
// var result = query.ToList();
var rowcount = session.QueryOver<Organism>()
    .Select(Projections.Count(Projections.Id()))
    .FutureValue<int>().Value;
var result = query.ToList();
int iRowCount = rowcount.Value();


0 commentaires