Antworten:
ICriteria
hat eine SetFirstResult(int i)
Methode, die den Index des ersten Elements angibt, das Sie erhalten möchten (im Grunde die erste Datenzeile auf Ihrer Seite).
Es gibt auch eine SetMaxResults(int i)
Methode, die die Anzahl der Zeilen angibt, die Sie erhalten möchten (dh Ihre Seitengröße).
Dieses Kriterienobjekt erhält beispielsweise die ersten 10 Ergebnisse Ihres Datenrasters:
criteria.SetFirstResult(0).SetMaxResults(10);
Sie können auch die Futures-Funktion in NHibernate nutzen, um die Abfrage auszuführen und die Gesamtzahl der Datensätze sowie die tatsächlichen Ergebnisse in einer einzigen Abfrage abzurufen.
Beispiel
// 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>();
Um die Gesamtzahl der Datensätze zu erhalten, gehen Sie wie folgt vor:
int iRowCount = rowCount.Value;
Eine gute Diskussion darüber, was Futures Ihnen bieten, finden Sie hier .
Ab NHibernate 3 können Sie Folgendes verwenden QueryOver<T>
:
var pageRecords = nhSession.QueryOver<TEntity>()
.Skip((PageNumber - 1) * PageSize)
.Take(PageSize)
.List();
Möglicherweise möchten Sie Ihre Ergebnisse auch explizit wie folgt bestellen:
var pageRecords = nhSession.QueryOver<TEntity>()
.OrderBy(t => t.AnOrderFieldLikeDate).Desc
.Skip((PageNumber - 1) * PageSize)
.Take(PageSize)
.List();
.Skip(PageNumber * PageSize)
Auf diese Weise werden bei einer Seitengröße von 10 niemals die ersten 10 Zeilen abgerufen. Ich bearbeite, um die Formel korrekt zu machen. Angenommen, konzeptionell PageNumber
sollte nicht 0 sein. Es sollte mindestens 1 sein.
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); }
}
Gibt es beim Paging von Daten eine andere Möglichkeit, ein typisiertes Ergebnis von MultiCriteria zu erhalten, oder tun alle das Gleiche wie ich?
Vielen Dank
Wie wäre es mit Linq to NHibernate, wie in diesem Blog-Beitrag von Ayende beschrieben?
Codebeispiel:
(from c in nwnd.Customers select c.CustomerID)
.Skip(10).Take(10).ToList();
Und hier ist ein ausführlicher Beitrag des NHibernate-Teamblogs zum Datenzugriff mit NHibernate, einschließlich der Implementierung von Paging.
Höchstwahrscheinlich möchten Sie in einer GridView einen Datenabschnitt plus die Gesamtzahl der Zeilen (Zeilenanzahl) der Gesamtdatenmenge anzeigen, die Ihrer Abfrage entspricht.
Sie sollten eine MultiQuery verwenden, um sowohl die Abfrage Select count (*) als auch die Abfragen .SetFirstResult (n) .SetMaxResult (m) in einem einzigen Aufruf an Ihre Datenbank zu senden.
Beachten Sie, dass das Ergebnis eine Liste ist, die zwei Listen enthält, eine für die Datenscheibe und eine für die Anzahl.
Beispiel:
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];
Ich schlage vor, dass Sie eine bestimmte Struktur erstellen, um mit Paginierung umzugehen. So etwas wie (ich bin ein Java-Programmierer, aber das sollte leicht zuzuordnen sein):
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()
}
Ich habe keine Implementierung bereitgestellt , aber Sie können die von @Jon vorgeschlagenen Methoden verwenden . Hier ist eine gute Diskussion, die Sie sich ansehen können.