NHibernate ile nasıl çağrı yapabilirsiniz?


107

Örneğin, bir ASP.NET web sayfasında bir ızgara görünümü denetimini yalnızca görüntülenen satır sayısı için gerekli verilerle doldurmak istiyorum. NHibernate bunu nasıl destekleyebilir?

Yanıtlar:


111

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

1
Bu, Linq (NH'ye) sözdiziminin nasıl görüneceğidir - Güzel.
MotoWilliams

13
Çağrı cihazınızı oluşturmak için toplam satır sayısını almak için ayrı bir işlem yapmanız gerekeceğini unutmamak önemlidir.
Kevin Pang

1
Bu, SQL Server'da bir SELECT TOP sorgusu gerçekleştirir. SetFirstResult (1) .SetMaxResult (2) ile deneyin;
Chris S

4
Bu önceki yorum NHibernate.Dialect.MsSql2000Dialect kullanıyor, NHibernate.Dialect.MsSql2005Dialect
Chris S

IQuery aynı işlevlere sahiptir, bu nedenle HQL ile de kullanılabilir.
goku_da_master

87

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 .


3
Bu harika. Vadeli işlemler, çok kriterlerin sözdizimsel karmaşıklığı olmadan çok kriterli gibi çalışır.
DavGarcia

Vadeli İşlemler hakkındaki yazıyı okuduktan sonra, tüm veritabanı sorgularım için Future'ı kullanmam gerekip gerekmediğini merak ediyorum ... Dezavantajı nedir? :)
hakksor

46

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 PageNumberolarak 0 olmaması gerektiğini varsayarsak, minimum 1 olmalıdır.
Amit Joshi

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

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


23

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 .


Nhibernate'e linq'in katkı paketinde olduğuna ve NHibernate 2.0 sürümüne dahil edilmediğine dikkat edin
Richard

11

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

6

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 .


0

2 kriter tanımlamanıza gerek yok, birini tanımlayıp klonlayabilirsiniz. NHibernate kriterlerini klonlamak için basit bir kod kullanabilirsiniz:

var criteria = ... (your criteria initializations)...;
var countCrit = (ICriteria)criteria.Clone();
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.