Yanıtlar:
ICriteria
SetFirstResult(int i)
almak istediğiniz ilk öğenin dizinini gösteren bir yönteme sahiptir (temelde sayfanızdaki ilk veri satırı).
Ayrıca, SetMaxResults(int i)
almak istediğiniz satır sayısını (yani, sayfa boyutunuzu) gösteren bir yöntemi vardır .
Örneğin, bu ölçüt nesnesi, veri ızgaranızın ilk 10 sonucunu alır:
criteria.SetFirstResult(0).SetMaxResults(10);
NHibernate'deki Futures özelliğinden yararlanarak sorguyu yürüterek toplam kayıt sayısını ve gerçek sonuçları tek bir sorguda alabilirsiniz.
Misal
// 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>();
Toplam kayıt sayısını elde etmek için şunları yaparsınız:
int iRowCount = rowCount.Value;
Futures'ın size ne kazandırdığına dair güzel bir tartışma burada .
NHibernate 3 ve üzeri sürümlerde şunları kullanabilirsiniz QueryOver<T>
:
var pageRecords = nhSession.QueryOver<TEntity>()
.Skip((PageNumber - 1) * PageSize)
.Take(PageSize)
.List();
Ayrıca sonuçlarınızı şu şekilde açık bir şekilde sıralamak isteyebilirsiniz:
var pageRecords = nhSession.QueryOver<TEntity>()
.OrderBy(t => t.AnOrderFieldLikeDate).Desc
.Skip((PageNumber - 1) * PageSize)
.Take(PageSize)
.List();
.Skip(PageNumber * PageSize)
bu şekilde, sayfa boyutu 10 ise, hiçbir zaman ilk 10 satırı almayacaktır. Formülü doğru yapmak için düzenleme yapıyorum. Kavramsal PageNumber
olarak 0 olmaması gerektiğini varsayarsak, minimum 1 olmalıdır.
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); }
}
Verileri sayfalandırırken, MultiCriteria'dan yazılı sonuç almanın başka bir yolu var mı yoksa herkes aynısını benim gibi mi yapıyor?
Teşekkürler
Ayende'nin yazdığı bu blog yazısında tartışıldığı gibi Linq'den NHibernate'e kullanmaya ne dersiniz ?
Kod Örneği:
(from c in nwnd.Customers select c.CustomerID)
.Skip(10).Take(10).ToList();
Ve burada NHibernate ekip bloğunun, sayfalamanın uygulanması dahil olmak üzere NHibernate ile Veri Erişimi üzerine ayrıntılı bir gönderisi var .
Büyük olasılıkla bir GridView'da bir veri dilimi artı sorgunuzla eşleşen toplam veri miktarının toplam satır sayısını (satır sayısı) göstermek isteyeceksiniz.
Tek bir çağrı ile veritabanınıza hem Select count (*) sorgusu hem de .SetFirstResult (n) .SetMaxResult (m) sorgularını göndermek için bir MultiQuery kullanmalısınız.
Sonucun, biri veri dilimi ve biri de sayım için olmak üzere 2 listeyi içeren bir liste olacağını unutmayın.
Misal:
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];
Sayfalandırmayla başa çıkmak için belirli bir yapı oluşturmanızı öneririm. Şöyle bir şey (Ben bir Java programcısıyım, ancak eşlemesi kolay olmalı):
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()
}
Ben bir uygulama sağlamadım ama @Jon tarafından önerilen yöntemleri kullanabilirsiniz . İşte göz atmanız için iyi bir tartışma .