Comment faire de la pagination avec NHibernate?

Par exemple, je souhaite remplir un contrôle gridview dans une page Web ASP.NET avec uniquement les données nécessaires pour le nombre de lignes affichées. Comment NHibernate peut-il supporter cela?

ICriteria a une SetFirstResult(int i) , qui indique l’index du premier élément que vous souhaitez obtenir (essentiellement la première ligne de données de votre page).

Il a également une SetMaxResults(int i) , qui indique le nombre de lignes que vous souhaitez obtenir (c’est-à-dire la taille de votre page).

Par exemple, cet object de critère obtient les 10 premiers résultats de votre grid de données:

 criteria.SetFirstResult(0).SetMaxResults(10); 

Vous pouvez également profiter de la fonctionnalité Futures dans NHibernate pour exécuter la requête afin d’obtenir le nombre total d’enregistrements ainsi que les résultats réels dans une seule requête.

Exemple

  // Get the total row count in the database. var rowCount = this.Session.CreateCriteria(typeof(EventLogEntry)) .Add(Expression.Between("Timestamp", startDate, endDate)) .SetProjection(Projections.RowCount()).FutureValue(); // Get the actual log ensortinges, respecting the paging. var results = this.Session.CreateCriteria(typeof(EventLogEntry)) .Add(Expression.Between("Timestamp", startDate, endDate)) .SetFirstResult(pageIndex * pageSize) .SetMaxResults(pageSize) .Future(); 

Pour obtenir le nombre total d’enregistrements, procédez comme suit:

 int iRowCount = rowCount.Value; 

Une bonne discussion de ce que l’avenir vous offre est ici .

Dans NHibernate 3, vous pouvez utiliser QueryOver

 var pageRecords = nhSession.QueryOver() .Skip(PageNumber * PageSize) .Take(PageSize) .List(); 

Vous voudrez peut-être également ordonner explicitement vos résultats comme ceci:

 var pageRecords = nhSession.QueryOver() .OrderBy(t => t.AnOrderFieldLikeDate).Desc .Skip(PageNumber * PageSize) .Take(PageSize) .List(); 
 public IList GetPagedData(int page, int pageSize, out long count) { try { var all = new List(); ISession s = NHibernateHttpModule.CurrentSession; IList results = s.CreateMultiCriteria() .Add(s.CreateCriteria(typeof(Customer)).SetFirstResult(page * pageSize).SetMaxResults(pageSize)) .Add(s.CreateCriteria(typeof(Customer)).SetProjection(Projections.RowCountInt64())) .List(); foreach (var o in (IList)results[0]) all.Add((Customer)o); count = (long)((IList)results[1])[0]; return all; } catch (Exception ex) { throw new Exception("GetPagedData Customer da hata", ex); } } 

Lorsque vous paginez des données, y a-t-il un autre moyen d’obtenir un résultat typescript de MultiCriteria ou tout le monde fait la même chose comme moi?

Merci

Que diriez-vous d’utiliser Linq to NHibernate comme discuté dans cet article de blog par Ayende?

Exemple de code:

 (from c in nwnd.Customers select c.CustomerID) .Skip(10).Take(10).ToList(); 

Et voici un article détaillé du blog de l’équipe NHibernate sur l’ access aux données avec NHibernate, y compris la mise en œuvre de la pagination.

Dans un GridView, vous souhaiterez probablement afficher une tranche de données plus le nombre total de lignes (nombre de lignes) de la quantité totale de données correspondant à votre requête.

Vous devez utiliser MultiQuery pour envoyer la requête Select count (*) et les requêtes .SetFirstResult (n) .SetMaxResult (m) à votre firebase database en un seul appel.

Notez que le résultat sera une liste contenant 2 listes, une pour la tranche de données et une pour le compte.

Exemple:

 IMultiQuery multiQuery = s.CreateMultiQuery() .Add(s.CreateQuery("from Item i where i.Id > ?") .SetInt32(0, 50).SetFirstResult(10)) .Add(s.CreateQuery("select count(*) from Item i where i.Id > ?") .SetInt32(0, 50)); IList results = multiQuery.List(); IList items = (IList)results[0]; long count = (long)((IList)results[1])[0]; 

Je vous suggère de créer une structure spécifique pour traiter la pagination. Quelque chose comme (je suis un programmeur Java, mais cela devrait être facile à cartographier):

 public class Page { private List results; private int pageSize; private int page; public Page(Query query, int page, int pageSize) { this.page = page; this.pageSize = pageSize; results = query.setFirstResult(page * pageSize) .setMaxResults(pageSize+1) .list(); } public List getNextPage() public List getPreviousPage() public int getPageCount() public int getCurrentPage() public void setPageSize() } 

Je n’ai pas fourni d’implémentation, mais vous pouvez utiliser les méthodes proposées par @Jon . Voici une bonne discussion à suivre.