आप NHibernate के साथ पेजिंग कैसे कर सकते हैं?


107

उदाहरण के लिए, मैं एक ASP.NET वेब पेज में ग्रिडव्यू कंट्रोल को केवल प्रदर्शित # पंक्तियों के लिए आवश्यक डेटा के साथ आबाद करना चाहता हूं। NHibernate इसका समर्थन कैसे कर सकता है?

जवाबों:


111

ICriteria एक SetFirstResult(int i) विधि है, जो पहले आइटम के सूचकांक को इंगित करता है जिसे आप प्राप्त करना चाहते हैं (मूल रूप से आपके पृष्ठ में पहली डेटा पंक्ति)।

यह भी एक SetMaxResults(int i) विधि , जो आपके द्वारा प्राप्त की जाने वाली पंक्तियों की संख्या को इंगित करता है (यानी, आपके पृष्ठ का आकार)।

उदाहरण के लिए, इस मानदंड ऑब्जेक्ट को आपके डेटा ग्रिड के पहले 10 परिणाम मिलते हैं:

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

1
यह बहुत ज्यादा है क्या Linq (NH को) सिंटैक्स वैसे भी दिखेगा - नाइस।
मोटोविलियम्स

13
यह ध्यान रखना महत्वपूर्ण है कि आपको अपने पेजर को प्रस्तुत करने के लिए कुल पंक्ति गणना को पुनः प्राप्त करने के लिए एक अलग लेनदेन को निष्पादित करना होगा।
केविन पैंग

1
यह SQL सर्वर में SELECT TOP क्वेरी करता है। इसे SetFirstResult (1) .SetMaxResult (2) के साथ आज़माएँ;
क्रिस एस

4
पिछली टिप्पणी NHibernate.Dialect.MsSql2000 उपयोग कर रही है। नहीं NHibernate.Dialect.MsSql2005Dialect
क्रिस एस

IQuery के समान कार्य हैं, इसलिए इसका उपयोग HQL के साथ भी किया जा सकता है।
गोकू_डा_मास्टर

87

आप कुल रिकॉर्ड संख्या के साथ-साथ एक ही क्वेरी में वास्तविक परिणाम प्राप्त करने के लिए क्वेरी को निष्पादित करने के लिए NHibernate में फ्यूचर्स सुविधा का लाभ भी ले सकते हैं।

उदाहरण

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

कुल रिकॉर्ड संख्या प्राप्त करने के लिए, आप निम्न कार्य करते हैं:

int iRowCount = rowCount.Value;

फ्यूचर्स आपको क्या देता है इसकी एक अच्छी चर्चा यहाँ है


3
यह भी खूब रही। फ्यूचर्स मल्टीक्रिटिया की तरह वाक्य रचना की जटिलता के बिना मल्टीक्रिटिया की तरह काम करता है।
दावारसिया

फ्यूचर्स के बारे में पोस्ट पढ़ने के बाद मैं सोच रहा हूं कि क्या मुझे अपने सभी डेटाबेस प्रश्नों के लिए भविष्य का उपयोग करना चाहिए ... क्या दोष है? :)
हर्कसर

46

NHibernate 3 और इसके बाद के संस्करण से, आप उपयोग कर सकते हैं QueryOver<T>:

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

आप इस तरह से अपने परिणाम स्पष्ट रूप से देना चाहते हैं:

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

.Skip(PageNumber * PageSize)इस तरह, यदि पृष्ठ का आकार 10 है, तो यह पहले 10 पंक्तियों को पुनः प्राप्त नहीं करेगा। मैं सूत्र को सही बनाने के लिए संपादन कर रहा हूं। यह मानते हुए कि वैचारिक रूप से, PageNumber0. नहीं होना चाहिए। यह न्यूनतम 1. होना चाहिए।
अमित जोशी

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

जब पेजिंग डेटा मल्टीक्रिटेरिया से टाइप करने के लिए एक और तरीका है या हर कोई मेरे जैसा ही करता है?

धन्यवाद


23

कैसे इस ब्लॉग पोस्ट में चर्चा के रूप में NHibernate को Linq का उपयोग करने के बारे में में आयेंडे द्वारा की गई अनुसार लिनेक को एनएचबर्नेट के ?

कोड नमूना:

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

और यहाँ NHibernate टीम ब्लॉग द्वारा डेटा एक्सेस विथ NHibernate सहित पेजिंग को लागू करने के लिए एक विस्तृत पोस्ट है ।


नोट लिन्क से निबरनेट को कंट्रीब्यूट पैकेज में शामिल किया गया है और NHibernate 2.0 रिलीज में शामिल नहीं है
रिचर्ड

11

एक GridView में सबसे अधिक संभावना है कि आप डेटा का एक टुकड़ा दिखाना चाहते हैं, जो आपकी क्वेरी से मेल खाते डेटा की कुल मात्रा (पंक्तियों) की कुल संख्या।

आपको एक ही कॉल में अपने डेटाबेस में सेलेक्ट काउंट (*) क्वेरी और .SetFirstResult (n) .SetMaxResult (m) दोनों क्वेरी भेजने के लिए एक MultiQuery का उपयोग करना चाहिए।

नोट परिणाम एक सूची होगी जिसमें 2 सूचियां होंगी, एक डेटा स्लाइस के लिए और एक गणना के लिए।

उदाहरण:

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

मेरा सुझाव है कि आप पृष्ठांकन से निपटने के लिए एक विशिष्ट संरचना बनाते हैं। कुछ ऐसा है (मैं जावा प्रोग्रामर हूं, लेकिन यह आसान होना चाहिए)

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

}

मैंने एक कार्यान्वयन की आपूर्ति नहीं की, लेकिन आप @Jon द्वारा सुझाए गए तरीकों का उपयोग कर सकते हैं । यहां आपके लिए एक अच्छी चर्चा है


0

आपको 2 मानदंड परिभाषित करने की आवश्यकता नहीं है, आप एक को परिभाषित कर सकते हैं और इसे क्लोन कर सकते हैं। NHibernate मानदंड को क्लोन करने के लिए आप एक सरल कोड का उपयोग कर सकते हैं:

var criteria = ... (your criteria initializations)...;
var countCrit = (ICriteria)criteria.Clone();
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.