Zum Beispiel möchte ich ein Gridview-Steuerelement in einer ASP.NET-Webseite mit nur den Daten füllen, die für die Anzahl der angezeigten Zeilen erforderlich sind. Wie kann NHibernate dies unterstützen?Wie können Sie mit NHibernate paging?
Antwort
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 hat auch eine SetMaxResults(int i)
Methode, die die Anzahl der Zeilen, die Sie erhalten möchten, zeigt (das heißt, Ihre Seitengröße).
Zum Beispiel dieser Kriterien Objekt erhält die ersten 10 Ergebnisse Ihrer Datenraster:
criteria.SetFirstResult(0).SetMaxResults(10);
Wie wäre es mit Linq zu NHibernate wie in this blog post von Ayende diskutiert?
Codebeispiel:
(from c in nwnd.Customers select c.CustomerID)
.Skip(10).Take(10).ToList();
Und hier ist eine detaillierte Post von dem NHibernate Team-Blog auf Data Access With NHibernate einschließlich Paging zu implementieren.
Hinweis Linq zu NHibernate im contrib-Paket und nicht in NHibernate enthalten 2.0 release – Richard
Ich schlage vor, dass Sie eine bestimmte Struktur mit Paginierung beschäftigen erstellen. So etwas wie (Ich bin ein Java-Programmierer, aber das sollte zur Karte leicht):
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 nicht eine Implementierung liefern, aber man konnte die Methoden von @Jon vorgeschlagen verwenden. Hier ist ein good discussion für Sie zu sehen.
Wahrscheinlich in einem Gridview Sie ein Stück Daten zeigen wollen und die Gesamtanzahl der Zeilen (rowcount) der Gesamtmenge der Daten, die Ihre Suchanfrage abgestimmt.
Sie sollten eine MultiQuery verwenden, um sowohl die Select count (*) -Abfrage als auch .SetFirstResult (n) .SetMaxResult (m) -Abfragen in einem einzigen Aufruf an Ihre Datenbank zu senden.
Beachten Sie, dass das Ergebnis eine Liste sein wird, die 2 Listen enthält, eine für die Datenscheibe und eine für die Zählung.
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];
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); }
}
Wenn Daten Paging gibt es eine andere Art und Weise resultieren aus mehrkriteriellen eingegeben werden oder jeder tut das gleiche wie ich gerade?
Dank
Sie auch die Vorteile der Futures verfügen in NHibernate die Abfrage auszuführen nehmen kann die gesamte Anzahl der Datensätze sowie die tatsächlichen Ergebnisse in einer einzigen Abfrage zu erhalten.
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>();
die gesamte Anzahl der Datensätze zu erhalten, tun Sie Folgendes:
int iRowCount = rowCount.Value;
Eine gute Diskussion darüber, was Futures geben Sie here ist.
Tolles Zeug, danke –
Das ist großartig. Futures funktioniert genau wie Multikriterien ohne die syntaktische Komplexität von Multikriterien. – DavGarcia
Nachdem ich den Beitrag über Futures gelesen habe, frage ich mich, ob ich Future für alle meine Datenbankabfragen verwenden soll ... Was ist der Nachteil? :) – hakksor
In 3 NHibernate können Sie verwenden QueryOver
var pageRecords = nhSession.QueryOver<TEntity>()
.Skip(PageNumber * PageSize)
.Take(PageSize)
.List();
Sie wollen auch explizit auf diese Ergebnisse wie bestellen:
var pageRecords = nhSession.QueryOver<TEntity>()
.OrderBy(t => t.AnOrderFieldLikeDate).Desc
.Skip(PageNumber * PageSize)
.Take(PageSize)
.List();
Das ist ziemlich genau das, was die Linq (zu NH) -Syntax sowieso aussehen würde - Nizza. – MotoWilliams
Es ist wichtig zu beachten, dass Sie eine separate Transaktion zum Abrufen der Gesamtzahl der Zeilen ausführen müssen, um Ihren Pager zu rendern. –
Dies führt eine SELECT TOP-Abfrage in SQL Server durch. Probieren Sie es mit SetFirstResult (1) .SetMaxResult (2); –