2009-09-03 5 views
6

मैं मूल रूप से NHibernate ICriteria इंटरफेस के साथ इस क्वेरी बनाने के लिए कोशिश कर रहा हूँ पर शामिल हों PrimaryKey, NonAggregateColumn: n AnotherTableNHibernate 2.1:</p> <p>SomeTable 1: वाम उर्फ ​​(ICriteria) के साथ सबक्वेरी

SomeTable स्तंभ होते हैं PrimaryKey, ForeignKey, AnotherNonAggregate, YetAnotherNonAggregate

SELECT 
     table1.NonAggregateColumn, 
     subquery.SubQueryAggregate1, 
     subquery.SubQueryAggregate2 
FROM 
     SomeTable AS table1 
     LEFT JOIN 
     (
      SELECT 
       table2.ForeignKey, 
       COUNT(table2.AnotherNonAggregate) AS SubQueryAggregate1, 
       AVG(table2.YetAnotherNonAggregate) AS SubQueryAggregate2 
      FROM AnotherTable AS table2 
      GROUP BY (table2.ForeignKey) 
    ) AS subquery ON subquery.ForeignKey = table1.PrimaryKey 
:
AnotherTable स्तंभ होते हैं

यह स्पष्ट है कि प्रोजेक्शन सबक्वायरी का उपयोग करना बहुत ही कुशल नहीं है, क्योंकि एसक्यूएल को तालिका को दो बार स्कैन करना है (प्रति एक प्रोजेक्शन सबक्वायरी)।

एकाधिक ग्रुप बीईएस का उपयोग करना भी कुशल नहीं है।

क्या इसके लिए कोई समाधान है? अब तक मैं कच्चे एसक्यूएल का उपयोग करने का प्रयास कर रहा हूं लेकिन जटिल रिपोर्टों के लिए यह अनावश्यक हो रहा है।

+0

क्या आप अपना प्रश्न स्पष्ट कर सकते हैं? जो क्वेरी आप दिखा रहे हैं वह देशी वर्ग है। क्या यह पहले से ही अपेक्षित डेटा वापस कर देता है? आप इसे मानदंडों में बदलना चाहते हैं। एचक्यूएल क्यों नहीं? –

+0

उल्लेख करने के लिए भूल गए: आप एक ओआरएम का उपयोग कर रहे हैं। तो एक प्रश्न लिखने के लिए, आपको टेबल और विदेशी कुंजी के बारे में बहुत अधिक परवाह नहीं है। संस्थाओं और मानचित्रण परिभाषाओं में बहुत अधिक महत्वपूर्ण हैं। तो ये टेबल मैप किए गए कैसे हैं? क्या कुछटेबल में कोई सूची है? क्या एटटेबल में कोई संदर्भ है? अथवा दोनों? –

+0

हां, मूल क्वेरी एक रिपोर्ट के लिए आवश्यक डेटा देता है। मैं NHibernate 2.1 का उपयोग कर रहा हूँ। मानदंड एपीआई को NHLambdaExtensions (जिसे मैं भी उपयोग कर रहा हूं) के माध्यम से मजबूत टाइपिंग क्षमता के कारण प्राथमिकता दी जाती है। मैं एसक्यूएल स्पष्ट और पढ़ने में आसान बनाने के लिए कुछटेबल, अन्यटेबल नामों का उपयोग कर रहा हूं। यह असली वस्तुओं का एक कल्पित दर्पण है। कुछटेबल मैप किए गए ऑब्जेक्ट में एक और टूटे ऑब्जेक्ट्स का एक से अधिक संग्रह है। –

उत्तर

2

दुर्भाग्यवश, मानदंड थोड़ा सीमित है।

इस प्रयास करें:

session.CreateCriteria(typeof(SomeTable), "st") 
    .SetProjection(Projections.ProjectionList() 
    .Add(Projections.GroupProperty("st.id")) 
    .Add(Projections.GroupProperty("st.NonAggregateColumn")) 
    .Add(Projections.RowCount(), "rowcount") 
    .Add(Projections.Avg("at.YetAnotherNonAggregate"), "avg")); 
    .CreateCriteria("st.OtherTables", "at", JoinType.InnerJoin) 
    .List<object[]>(); 

आप शायद थोड़ा चारों ओर खेलने के लिए की जरूरत है, यह एक अनुमान के अधिक है। यह भी इस तरह असंभव हो सकता है।

select 
    st.id, 
    st.NonAggregateColumn, 
    count() as "rowcount", 
    avg(at.YetAnotherNonAggregate) as "avg" 
from 
    SomeTable st inner join AnotherTable at on ... 
group by 
    st.id, 
    st.NonAggregateColumn 

आम तौर पर:

  • आप DetachedCriteria का उपयोग कर सबक्वेरी कर सकते हैं

    वह कुछ इस तरह प्रस्तुत करना चाहिए। अधिक जानकारी के लिए the docs देखें।

  • आप मानदंड के साथ एक कार्टशियन उत्पाद नहीं बना सकते हैं और जहां खंड में फ़िल्टर कर सकते हैं। (यह केवल एचक्यूएल के साथ काम करता है)।
  • उपखंडों को खंड से जोड़ा नहीं जा सकता है (क्योंकि इसके परिणामस्वरूप एक कार्टशियन उत्पाद होगा)। आप उन्हें केवल उस खंड (in, exists इत्यादि) में डाल सकते हैं)
  • आप शायद AnotherTable से शुरू कर सकते हैं और SomeTable पर नेविगेट कर सकते हैं। यह एक वैकल्पिक समाधान हो सकता है।
+1

मुझे समाधान से समूह के बारे में पता है, लेकिन समस्या यह है कि वास्तविक दुनिया की रिपोर्ट में, मुझे इतने सारे स्तंभों से समूह करना होगा, कि एसक्यूएल रिकॉर्ड के 1000s के लिए एक बड़ा सौदा धीमा करने जा रहा है, ओह ठीक है, शायद मैं एनएचबीर्नेट के स्रोत का अध्ययन करने और इस दिन योगदान करने की कोशिश कर सकता हूं ... मैं अब के लिए कच्चे एसक्यूएल का उपयोग करूंगा, धन्यवाद के लिए धन्यवाद। –

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