Pergunta

Por exemplo, quero preencher um controle gridview em uma página da web ASP.NET com apenas os dados necessários para o número de linhas exibidas.Como o NHibernate pode suportar isso?

Foi útil?

Solução

ICriteria tem um SetFirstResult(int i) método, que indica o índice do primeiro item que você deseja obter (basicamente a primeira linha de dados da sua página).

Também tem um SetMaxResults(int i) método, que indica o número de linhas que você deseja obter (ou seja, o tamanho da sua página).

Por exemplo, este objeto de critérios obtém os primeiros 10 resultados da sua grade de dados:

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

Outras dicas

Você também pode aproveitar o recurso Futures do NHibernate para executar a consulta e obter a contagem total de registros, bem como os resultados reais em uma única consulta.

Exemplo

 // 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 obter a contagem total de registros, faça o seguinte:

int iRowCount = rowCount.Value;

Uma boa discussão sobre o que os futuros oferecem é aqui.

Do NHibernate 3 e superior, você pode usar QueryOver<T>:

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

Você também pode ordenar explicitamente seus resultados assim:

var pageRecords = nhSession.QueryOver<TEntity>()
            .OrderBy(t => t.AnOrderFieldLikeDate).Desc
            .Skip((PageNumber - 1) * PageSize)
            .Take(PageSize)
            .List();
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); }
      }

Ao paginar dados, existe outra maneira de obter o resultado digitado do MultiCriteria ou todos fazem o mesmo como eu?

Obrigado

Que tal usar o Linq to NHibernate conforme discutido em esta postagem do blog por Ayende?

Amostra de código:

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

E aqui está uma postagem detalhada do blog da equipe do NHibernate em Acesso a dados com NHibernate incluindo a implementação de paginação.

Provavelmente em um GridView você desejará mostrar uma fatia de dados mais o número total de linhas (rowcount) da quantidade total de dados que corresponderam à sua consulta.

Você deve usar uma MultiQuery para enviar a consulta Select count(*) e as consultas .SetFirstResult(n).SetMaxResult(m) para seu banco de dados em uma única chamada.

Observe que o resultado será uma lista que contém 2 listas, uma para a fatia de dados e outra para a contagem.

Exemplo:

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

Sugiro que você crie uma estrutura específica para lidar com a paginação.Algo como (sou programador Java, mas deve 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()

}

Não forneci uma implementação, mas você poderia usar os métodos sugeridos por @Jon.Aqui está um boa discussão para você dar uma olhada.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top