2012-05-29 21 views
7

पर मैं जो मैंGroupBy SqlFunction QueryOver

var accounts = this.SessionManager.GetActiveSession().QueryOver<Account>(); 

var q = accounts.Select(Projections.Distinct(
     Projections.SqlFunction("substring", 
           NHibernateUtil.String, 
           Projections.Property("Name"), 
           Projections.Constant(1), 
           Projections.Constant(1)))); 

का उपयोग कर अधिग्रहण सभी भिन्न खाता नाम उपसर्ग (AZ) की एक सूची है हालांकि मुझे क्या करना चाहते हैं के बजाय एक अलग सूची लौटने का है समूह उपसर्गों और वापसी है उस उपसर्ग के साथ शुरू होने वाले खातों की संख्या, लेकिन मुझे यकीन नहीं है कि क्वेरी का उपयोग करके समूह को कैसे निष्पादित किया जाए क्योंकि यह मानक linq के रूप में सरल नहीं है।

कारण मैं क्वेरीओवर का उपयोग कर रहा हूं और क्वेरी नहीं है क्योंकि किसी कारण से सबस्ट्रिंग फ़ंक्शन स्मृति में किया जा रहा है, न कि डेटाबेस सर्वर पर।

यह यह है कि मैं क्या करने की कोशिश की, लेकिन मैं अभिव्यक्ति SqlFunction में

पहचाने न जाने वाले विधि कॉल निम्न त्रुटि प्राप्त है (

संपादित कैसे मैं आमतौर पर यह

var prefixes = (from acc in this.SessionManager.GetActiveSession().Query<Account>() 
       group acc by acc.Name.Substring(0, 1) 
       into grp 
       select new 
         { 
         Prefix = grp.Key, 
         Count = grp.Count() 
         }); 
करना होगा कि "सबस्ट्रिंग ", NHibernateUtil.String, नया [] {संपत्ति (" नाम "), निरंतर (कनवर्ट (1)), कॉन्स्टेंट (कनवर्ट (1))}

var accounts = this.SessionManager.GetActiveSession().QueryOver<Account>().Select(
      Projections.Group<string>(x => Projections.SqlFunction("substring", NHibernateUtil.String, 
                 Projections.Property("Name"), Projections.Constant(1), 
                 Projections.Constant(1))), 
      Projections.Count<string>(x => Projections.SqlFunction("substring", NHibernateUtil.String, 
                 Projections.Property("Name"), Projections.Constant(1), 
                 Projections.Constant(1))) 

     ); 

उत्तर

4

पर नहीं सूचीबद्ध करें आप Projections.SqlGroupProjection का उपयोग कर ऐसा कर सकते हैं यदि सब कुछ विफल हो जाता है!

var accounts = _busDb.Session.QueryOver<QueueEntity>() 
     .Select(
      Projections.SqlGroupProjection(
       "SUBSTRING({alias}.Name, 1) as FirstChar", 
       "SUBSTRING({alias}.Name, 1)", 
       new[] {"FirstChar"}, 
       new[] {NHibernateUtil.String}), 
      Projections.Count("id")); 

पहला तर्क है क्या चयन में चुना जाता है, दूसरा तर्क क्या, के आधार पर वर्गीकृत किया जाता है तीसरा तर्क स्तंभ (रों) कि चुने गए हैं का नाम है, और चौथे तर्क प्रकार है डेटा का चयन किया जा रहा है।

+0

सबस्ट्रिंग फ़ंक्शन को एक अतिरिक्त पैरामीटर की आवश्यकता होती है लेकिन इससे समस्या हल हो जाती है। बहुत धन्यवाद – JConstantine

3

आपकी सूची कितनी बड़ी है? यदि यह 1000 से भी कम है मैं आइटम सूची इकट्ठा होगा से एसक्यूएल सर्वर फिर सूची के खिलाफ क्वेरी द्वारा अपने नियमित रूप से समूह ने कैसा प्रदर्शन

var sqlout= (from acc in this.SessionManager.GetActiveSession().Query<Account>() 
      select new 
        { 
        Name = acc.Name, 
        col1= acc.col1 
        }).TolList(); 

और फिर

var prefixes = (from acc in sqlout 
      group acc by acc.Name.Substring(0, 1) 
      into grp 
      select new 
        { 
        Prefix = grp.Key, 
        Count = grp.Count() 
        }); 

सबस्ट्रिंग समारोह C# पर अपनी चल रहा है के बाद से यहाँ काम करेगा एसक्यूएल सर्वर

+0

फिलहाल हम 20k से अधिक खातों वाले सूचियों को देख रहे हैं। :( – JConstantine

3

क्या आपने अलग स्तंभ में नाम के पहले अक्षर को संग्रहीत करके सबस्ट्रिंग क्वेरी की आवश्यकता को समाप्त करने पर विचार किया है?

मान लें कि आप SQL सर्वर का उपयोग कर रहे हैं, तो आप तालिका को सम्मिलित/अपडेट करने वाले कोड को अपडेट करने से बचने के लिए इसे एक सतत गणना कॉलम बना सकते हैं।

इस कॉलम वाले इंडेक्स को जोड़ने की क्षमता आपको अपने क्वेरी प्रदर्शन को बेहतर बनाने में भी मदद करनी चाहिए।

+0

+1 दीर्घकालिक समाधान के रूप में यह शायद इस समस्या से निपटने के लिए हमें जिस तरीके से जाना होगा, वह निश्चित रूप से इसे जारी रखेगा। मन – JConstantine

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