¿Cómo se puede hacer una búsqueda con NHibernate?

Por ejemplo, quiero rellenar un control gridview en una página web ASP.NET con solo los datos necesarios para el # de filas mostradas. ¿Cómo puede NHibernate respaldar esto?

ICriteria tiene un SetFirstResult(int i) , que indica el índice del primer elemento que desea obtener (básicamente la primera fila de datos en su página).

También tiene un SetMaxResults(int i) , que indica el número de filas que desea obtener (es decir, el tamaño de su página).

Por ejemplo, este objeto de criterio obtiene los primeros 10 resultados de su cuadrícula de datos:

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

También puede aprovechar la función Futures en NHibernate para ejecutar la consulta y obtener el recuento total de registros y los resultados reales en una sola consulta.

Ejemplo

  // 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 entries, respecting the paging. var results = this.Session.CreateCriteria(typeof(EventLogEntry)) .Add(Expression.Between("Timestamp", startDate, endDate)) .SetFirstResult(pageIndex * pageSize) .SetMaxResults(pageSize) .Future(); 

Para obtener el conteo total de registros, haga lo siguiente:

 int iRowCount = rowCount.Value; 

Una buena discusión de lo que los futuros le dan está aquí .

En NHibernate 3 puede usar QueryOver

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

También es posible que desee ordenar explícitamente sus resultados de esta manera:

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

Cuando hay otra forma de obtener los resultados de paginación de los resultados de MultiCriteria, ¿o todos hacen lo mismo que yo?

Gracias

¿Qué hay de usar Linq a NHibernate como se explica en esta publicación de blog por Ayende?

Muestra de código:

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

Y aquí hay una publicación detallada del blog del equipo NHibernate sobre Acceso a datos con NHibernate, que incluye la implementación de paginación.

Lo más probable es que en un GridView desee mostrar un segmento de datos más el número total de filas (recuento de filas) de la cantidad total de datos que coinciden con su consulta.

Debe usar un MultiQuery para enviar las consultas Select count (*) y .SetFirstResult (n) .SetMaxResult (m) a su base de datos en una sola llamada.

Tenga en cuenta que el resultado será una lista que contiene 2 listas, una para el segmento de datos y otra para el recuento.

Ejemplo:

 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]; 

Sugiero que cree una estructura específica para manejar la paginación. Algo así como (soy progtwigdor de Java, pero debería ser fácil de mapear):

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

No proporcioné una implementación, pero podría usar los métodos sugeridos por @Jon . Aquí hay una buena discusión para que la eche un vistazo.