2008-09-10 16 views

Respuesta

107

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

También tiene un método 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 criterios obtiene los primeros 10 resultados de la cuadrícula de datos:

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

Esto es más o menos lo que la sintaxis de Linq (a NH) se vería de todos modos: agradable. – MotoWilliams

+13

Es importante tener en cuenta que deberá ejecutar una transacción por separado para recuperar el recuento total de filas para renderizar su busca. –

+1

Esto realiza una consulta SELECT TOP en SQL Server. Pruébalo con SetFirstResult (1) .SetMaxResult (2); –

23

¿Qué le parece usar Linq a NHibernate como se discutió en this blog post por Ayende?

Código de ejemplo:

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

Y aquí es un post detallado por el blog del equipo de NHibernate en Data Access With NHibernate incluyendo la implementación de paginación.

+0

Nota LINQ a Nhibernate se encuentra en el paquete de contribución y no se incluye en NHibernate 2.0 release – Richard

6

Sugiero que se crea una estructura específica para hacer frente a la paginación. Algo así como (soy un programador de Java, pero que debería ser fácil de mapa):

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

} 

que no proporcionó una implementación, pero se puede usar los métodos sugeridos por @Jon. Aquí hay un good discussion para que lo eche un vistazo.

11

Es muy probable 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]; 
31
public IList<Customer> GetPagedData(int page, int pageSize, out long count) 
     { 
      try 
      { 
       var all = new List<Customer>(); 

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

Durante la búsqueda de los datos es que hay otra manera de conseguir mecanografiado resultado de multicriterio o todo el mundo hace lo mismo como yo?

Gracias

87

También puede tomar ventaja de los futuros incluyen en NHibernate para ejecutar la consulta para obtener el registro de recuento total, así como 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<Int32>(); 

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

para obtener el recuento total del registro, haga lo siguiente:

int iRowCount = rowCount.Value; 

Una buena discusión de lo que te dan es Futuros here.

+1

Cosas geniales, gracias –

+3

Esto es genial. Futures funciona exactamente igual que multicriterios sin la complejidad sintáctica de la multicritería. – DavGarcia

+0

Después de leer la publicación sobre Futuros, me pregunto si debería usar Future para todas mis consultas a la base de datos ... ¿Cuál es el inconveniente? :) – hakksor

39

En NHibernate 3 puede utilizar QueryOver

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

También puede querer pedir explícitamente sus resultados como este:

var pageRecords = nhSession.QueryOver<TEntity>() 
      .OrderBy(t => t.AnOrderFieldLikeDate).Desc 
      .Skip(PageNumber * PageSize) 
      .Take(PageSize) 
      .List(); 
Cuestiones relacionadas