2011-02-07 11 views
8

मेरे पास एक ऐसा एप्लिकेशन है जो कुछ डेटा वेयरहाउसिंग सिद्धांतों का उपयोग करता है जैसे कि आयामी मॉडलिंग, काफी सरल डेटाबेस पर रिपोर्टिंग करने के लिए।एसक्यूएल में सांख्यिकीय क्वेरी - क्या यह NHibernate LINQ के साथ संभव है?

एक उदाहरण (सरलीकृत) इकाई नामित कॉल इस तरह दिखता है: के रूप में वे अप्रासंगिक हैं

public virtual long Id { get; set; } 
    public virtual string OriginatorNumber { get; set; } 
    public virtual string DestinationNumber { get; set; } 
    public virtual DateDimension DateDimension { get; set; } 

असली मॉडल के गुणों में से कुछ हटा दिया गया है। सरलीकृत DateDimension इस तरह दिखता है:

public virtual long Id { get; set; } 
    public virtual DateTime Date { get; set; } 
    public virtual int DayOfMonth { get; set; } 
    public virtual int Weekday { get; set; } 

इस तरह एक बहुत अधिक स्तंभ हैं - वे आवेदन सेटअप द्वारा वर्तमान दशक के लिए पॉप्यूलेट कर रहे हैं। इसलिए पूरे दशक में प्रत्येक तारीख की इस तालिका में एक पंक्ति होती है, और प्रत्येक कॉल के पास उस तिथि का लिंक होता है जो यह हुआ था। यह सब फ्लुएंट एनएचबेर्नेट में मैप किया गया है और ठीक काम कर रहा है।

अगर मैं कुछ रिपोर्टिंग करना चाहता हूं, तो मैं इसे 3.0 में बेहतर एनएचबेर्नेट LINQ प्रदाता के साथ आसानी से कर सकता हूं। हम LINQ का उपयोग बेहतर रखरखाव के लिए करना चाहते हैं जो हमें देता है, लेकिन अगर हमें वास्तव में जरूरी है, तो हम एचक्यूएल, आईसीआरटीरिया या यहां तक ​​कि सादे एसक्यूएल पर विचार करेंगे।

तो कहें कि मैं एक ऐसी रिपोर्ट बनाना चाहता हूं जो किसी निश्चित संख्या से कॉल की संख्या दिखाती है, जो सप्ताह के दिन तक विभाजित होती है। मुझे लगता है कि आसानी से इस तरह से कर सकते हैं:

 var query = Calls 
      .Where(c => c.OriginatorNumber == "402") 
      .GroupBy(c => c.DateDimension.Weekday) 
      .Select(g => new { Day = g.Key, Calls = g.Count() }); 

इस उदाहरण में, "कॉल" मूल रूप से एक IQueryable भंडार इंटरफेस के माध्यम से NHibernates LINQ प्रदाता (क्वेरी) से लौट आए है। ऊपर दी गई क्वेरी मुझे सही परिणाम देती है, एनएचबीर्नेट प्रोफाइलर मुझे दिखाता है कि एसक्यूएल बहुत इष्टतम है, सब ठीक है।

हालांकि, अगर मैं कुछ और अधिक उन्नत करना चाहता हूं, तो मैं अटक जाता हूं। मान लें कि मैं प्रति सप्ताह कॉल की औसत संख्या चाहता हूं। उपर्युक्त से बहुत दूर नहीं, है ना? मुझे बस परिणाम सेट में प्रत्येक सप्ताह के अनन्य तिथियों की संख्या जानने की आवश्यकता है, इसके द्वारा कॉल की कुल संख्या विभाजित करें, और हम सभी सेट हैं - है ना? खैर, नहीं, यह वह जगह है जहां मैं NHibernate LINQ प्रदाता की सीमाओं को हिट करना शुरू कर देता हूं।

.Select(g => g.Count()/g.GroupBy(c => c.DateDimension.Date).Count()); 

की तर्ज पर कुछ बहरहाल, यह सही क्वेरी में परिवर्तित नहीं करता है जब यह NHibernate में का उपयोग कर - वस्तुओं के लिए LINQ के साथ मैं यह करने के लिए एक प्रश्न का निर्माण कर सकता है। इसके बजाय, यह कॉल रिकॉर्ड के समान गणना (*) पर उपरोक्त में काउंटर() दोनों कॉल करता है, इसलिए परिणाम हमेशा होता है 1.

मैं निश्चित रूप से प्रत्येक कॉल, सप्ताह के दिन और तारीख के लिए पूछताछ कर सकता हूं नई अज्ञात वस्तु, फिर आवेदन पक्ष पर गणित करें, लेकिन पारंपरिक ज्ञान के अनुसार, यह जस्ट गलत (टीएम) है। मैं निराशा में ऐसा कर सकता हूं, थो, यहां तक ​​कि इसका अर्थ यह है कि जब टेबल एक लाख ++ कॉल तक बढ़ता है तो दर्द होता है।

नीचे एक SQL क्वेरी है जो मुझे वह परिणाम देता है जो मैं ढूंढ रहा हूं।

select ss.Weekday, AVG(cast(ss.Count as decimal)) 
from 
(
select dd.Weekday, dd.Date, COUNT(*) as Count 
from Call c 
left outer join DateDimension dd 
    on c.DateDimension_id = dd.Id 
where c.OriginatorNumber = '402' 
group by dd.Weekday, dd.Date 
) ss 
group by ss.Weekday 
order by ss.Weekday 

क्या यह NHibernate LINQ प्रदाता के साथ ऐसा करना संभव है? या, यदि यह संभव नहीं है, तो मुझे आवेदन को इंटरमीडिएरी परिणाम लाने और शेष करने से पहले मुझे कितना करीब मिल सकता है?

+0

शायद आप इसके बारे में गलत तरीके से जा रहे हैं। एक स्टार स्कीमा और पूर्व जनसंख्या गणना के उपायों के बारे में कैसे? – epitka

+0

अच्छा, यह एक दिलचस्प बिंदु है - हालांकि, मेरी समझ यह है कि "तथ्य" तालिका में प्रत्येक इकाई (यानी मेरे उदाहरण में कॉल) प्रत्येक प्रासंगिक आयाम तालिका में एक एफके है। मैं एक स्टार स्कीमा कैसे बना सकता हूं जो मुझे कॉल पीआर डेट को समझने में मदद करता है, और प्रत्येक कॉल रिकॉर्ड से इसे इंगित करता है? लेकिन आम तौर पर, मैं इस संभावना के लिए बहुत खुला हूं कि मैं इस बारे में गलत तरीके से जा रहा हूं। :) –

उत्तर

1

LINQ प्रदाता के साथ आप बहुत सी चीजें नहीं कर सकते हैं। एचक्यूएल या CreateCriteria का उपयोग करना कुछ ऐसा है जो आपको NHibernate के साथ स्वीकार करना होगा।

मैंने कोशिश नहीं की है, लेकिन ऐसा लगता है कि आप ऐसा करने में सक्षम होना चाहिए जो आप एचक्यूएल या CreateCriteria (DetatchedCriteria के साथ) का उपयोग करना चाहते हैं।

यदि आप बेताब हैं तो आप CreateSqlQuery का उपयोग करके सादे एसक्यूएल पर भी वापस आ सकते हैं।

+1

हाय, और आपके उत्तर के लिए धन्यवाद। हां, मुझे इस पर वापस आना पड़ सकता है - समस्या मूल रूप से है कि मैं अपने उपयोगकर्ताओं को IQuery के साथ IQueryable पर आधारित करना चाहता था, ताकि वे समूह के लिए IQueryable पास करने से पहले कहां() के साथ कुछ फ़िल्टरिंग कर सकें। यह बहुत ही सुरुचिपूर्ण होता - मुझे लगता है कि मुझे वास्तव में क्या करना चाहिए वह एक महान कोडर बन गया है और एनएचबीर्नेट में योगदान देता है। :) इनपुट के लिए धन्यवाद, मैं चीजों को करने के HQL और ICriteria तरीकों में देखता हूँ। –

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