2008-11-25 8 views
28

मैं NHibernate में मानदंड API का उपयोग करके अलग-अलग परिणाम प्राप्त करने का प्रयास कर रहा हूं। मुझे पता है कि यह एचक्यूएल का उपयोग कर संभव है, लेकिन मैं मानदंड एपीआई का उपयोग करके ऐसा करना पसंद करूंगा, क्योंकि मेरा बाकी ऐप केवल इस विधि का उपयोग करके लिखा गया है। मैं found this forum post, लेकिन इसे काम करने में सक्षम नहीं हूं। क्या अलग-अलग परिणाम सेट प्राप्त करने के लिए मानदंड API के साथ कोई तरीका है?मानदंड एपीआई का उपयोग कर NHibernate से अलग परिणाम सेट प्राप्त करें?

संपादित करें: ऐसा करने में, मैं प्राथमिक कुंजी कॉलम को भी बाहर करना चाहता था, जो एक पहचान भी है, और शेष विशिष्ट रिकॉर्ड प्राप्त करें। क्या इसे करने का कोई तरीका है? जैसा कि है, अलग-अलग रिकॉर्ड डुप्लीकेट लौट रहे हैं क्योंकि प्रत्येक पंक्ति के लिए प्राथमिक कुंजी अद्वितीय है, लेकिन अन्य सभी फ़ील्ड समान हैं।

उत्तर

23

इस पल में मंच पोस्ट को नहीं देख सकते हैं, इसलिए हो सकता है इस सवाल का जवाब नहीं है, लेकिन यदि आप एक DistinctRootEntityResultTransformer जोड़ सकते हैं (टूटी हुई लिंक?):

session.CreateCriteria(typeof(Product) 
    .Add(...) 
    .SetResultTransformer(new DistinctEntityRootTransformer()) 
+0

ठीक है, मैंने पहले कभी ऐसा नहीं किया है, इसलिए 1 त्वरित प्रश्न। मेरे पास प्राथमिक कुंजी है, जो पहचान क्षेत्र है। परिणामस्वरूप सेट से मैं उस क्षेत्र को कैसे बाहर निकाल सकता हूं ताकि अलग-अलग परिणाम वास्तव में अलग हो जाएं? अगर मैं समझ में नहीं आता तो मैं स्पष्ट कर सकता हूं। –

+0

मुझे नहीं पता कि यह संभव है या नहीं। आप अन्य क्षेत्रों के साथ एक डीटीओ बना सकते हैं और उस डीटीओ के खिलाफ पूछताछ कर सकते हैं, लेकिन इसे एचक्यूएल का उपयोग करने की आवश्यकता होगी। – Juanma

+0

DistinctEntityRootTransformer कहां से आता है? वीएस मेरे लिए इसे हल नहीं करेगा। क्या मैं कहीं एक असेंबली लापता हूं? – BuddyJoe

86

एक विशिष्ट क्वेरी आप प्रक्षेपण सेट कर सकते हैं करने के लिए अनुमानों के मानदंडों पर। डिस्टिंट। फिर आप उन स्तंभों को शामिल करते हैं जिन्हें आप वापस करना चाहते हैं। नतीजा तब परिणामस्वरूप ट्रांसफार्मर को एलियासटोबैन रीसेटल्ट ट्रांसफॉर्मर पर सेट करके एक दृढ़ता से टाइप की गई वस्तु में बदल दिया जाता है - जिस प्रकार से परिणाम को परिवर्तित किया जाना चाहिए। इस उदाहरण में मैं इकाई के समान ही उपयोग कर रहा हूं लेकिन आप विशेष रूप से इस क्वेरी के लिए एक और कक्षा बना सकते हैं।

ICriteria criteria = session.CreateCriteria(typeof(Person)); 
criteria.SetProjection(
    Projections.Distinct(Projections.ProjectionList() 
     .Add(Projections.Alias(Projections.Property("FirstName"), "FirstName")) 
     .Add(Projections.Alias(Projections.Property("LastName"), "LastName")))); 

criteria.SetResultTransformer(
    new NHibernate.Transform.AliasToBeanResultTransformer(typeof(Person))); 

IList<Person> people = criteria.List<Person>(); 

यह (कम से कम एसक्यूएल सर्वर में) के समान एसक्यूएल बनाता है:

SELECT DISTINCT FirstName, LastName from Person 

कृपया ध्यान रखें कि केवल गुण है कि आप अपने प्रक्षेपण में निर्दिष्ट परिणाम में से भरी हुई होगी हो।

इस विधि का लाभ यह है कि फ़िल्टरिंग आपके आवेदन में सभी परिणामों को वापस करने के बजाय डेटाबेस में किया जाता है और फिर फ़िल्टरिंग कर रहा है - जो DistinctRootEntityTransformer का व्यवहार है।

+0

क्या आप जानते हैं कि मैं बाल ऑब्जेक्ट ग्राफ़ हाइड्रेटेड कैसे हो सकता हूं? मैं इसे रूट की सभी कॉलम चुनने के लिए प्राप्त कर सकता हूं, जिसमें विदेशी कुंजी कॉलम भी शामिल हैं, लेकिन यह नहीं पता कि क्वेरी रिटर्न के बाद उन्हें लोड करने के लिए इसे कैसे प्राप्त किया जाए। – longday

+0

@ लांगडे मुझे नहीं लगता कि एनएचबीर्नेट ऐसा करना संभव है क्योंकि एक अलग प्रक्षेपण करके आप वास्तविक संस्थाओं से निपट नहीं रहे हैं (भले ही आप एक ही कक्षा का उपयोग कर रहे हों)। आप क्या कर सकते हैं अपने प्रक्षेपण में कई तालिकाओं के कॉलम शामिल हैं और परिणाम में उपयोग करने के लिए एक अलग वर्ग बनाएं जिसमें आपकी रुचि रखने वाली सभी संपत्तियां हैं। –

+0

यदि आप मानदंडों में उपनाम परिभाषित करते हैं तो यह काम नहीं करता है, क्योंकि यह कक्षा के सदस्यों के बीच उपनाम को देखना शुरू कर देगा, जो निश्चित रूप से नहीं मिल पा रहे हैं। –

6

इसके लायक होने के लिए, NHibernate: Optimising Queries with Projections ने मुझे मूल रूप से इसी समस्या के साथ मदद की।

+0

नोट: लिंक अब नहीं मिला है। – Thierry

+0

@ थिएरी धन्यवाद। लेखक ने अपना यूआरएल ले जाने के बाद से लिंक को अपडेट किया। –

-4

मैं भी गैर-विशिष्ट संख्या की वस्तुओं की समस्या में भाग गया (मैं अपनी मैपिंग फ़ाइल में एक fetch = "join" का उपयोग करता हूं)।

 var suppliers = (from supplier in session.Linq<Supplier>() 
         from product in supplier.Products 
         where product.Category.Name == produtCategoryName 
         select supplier).ToList().Distinct(); 
+9

गलत। इस मामले में विशिष्ट ग्राहक पक्ष किया जा रहा है। आप ToList() को कॉल कर रहे हैं, जो सभी परिणामों को वापस कर देता है। एनएचप्रोफ में देखें। –

+0

SetResultTransformer (नया DistinctEntityRootTransformer()) उत्तर में http://stackoverflow.com/questions/318157/get-distinct-result-set-from-nhibernate-using-criteria-api/318196#318196 लगभग समान ही करता है। अलग()। वे दोनों ग्राहक पक्ष परिवर्तन हैं। और वे लगभग बराबर हैं। –

-1

हम इस संभाल करने के लिए ... केवल आप अगर पर पढ़ा सभी के अधिकांश आधुनिक और शक्तिशाली और प्रभावशाली छोटे साधन का उपयोग कर रहे हैं: मैं समस्या है, जो निम्नलिखित तरीके से प्रयोग किया जाता है हल करने के लिए Linq करने के लिए इस्तेमाल किया Nhibernate 'फिर से भयानक के लिए तैयार ... और यह मापदंड से कोई लेना देना कुछ नहीं है ...

CurrentSession() 
    .QueryOver<GoodBadAndUgly> 
    .Where(...) 
    .TransformUsing(Transformers.DistinctRootEntity) 

इसलिए, यदि आप यहाँ आए हैं यह है कि तुम भी मानदंड के साथ खिलवाड़ से परहेज किया है इसके लिए कोई तरीका के लिए उम्मीद यद्यपि यद्यपि आपको पूरी तरह से उस दिशा में जाना होगा, बस अपने एसक्यूएल में 'DISTINCT' जोड़ने के लिए ... खोज आगे नहीं

संबंधित मुद्दे