2010-01-28 21 views
5

मैं LINQ से इकाइयों का उपयोग कर रहा हूं।यह linq अभिव्यक्ति क्यों काम नहीं कर रही है?

मेरे पास छात्र नामक एक टेबल है; इसमें आईडी और नाम है क्योंकि यह कॉलम है। आईडी एक प्राथमिक कुंजी है।

मैं छात्र का नाम चुनने और समान नाम वाले छात्रों की संख्या प्राप्त करने में सक्षम होना चाहता हूं।

तो उदाहरण के लिए मेरे पास यह मेरा टेबल डेटा होगा।

ID Name 
1 Bob 
2 Will 
3 Bob 

क्वेरी करने के बाद मैं इस तरह दिखने वाले छात्र वस्तुओं की एक सूची वापस कर दूंगा।

Name Quantity 
Bob  2 
Will 1 

मुझे लगता है कि यह स्टैक ओवरफ्लो के टैग पेज कैसे काम करता है; इसका नाम और मात्रा है।

वैसे भी, मैंने Student.cs नामक आंशिक कक्षा बनाई है जिसमें मैंने इस तरह की मात्रा संपत्ति जोड़ा है।

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

namespace MySite.Models 
{ 
    public partial class Student 
    { 
     private int _quantity; 

     public int Quantity 
     { 
      get { return _quantity; } 
      set { _quantity = value; } 
     } 
    } 
} 

मैं इस के साथ आया था, लेकिन मैं एक त्रुटि हो रही है ..

public IQueryable<Student> FindStudentsDistinctWithQuantity() 
    { 
     /*SELECT Name, COUNT(Name) AS Quantity 
     FROM Student 
     GROUP BY Name*/ 

     var students= (from s in db.Students 
        group s by s.Name into g 
        select new {Name = g.Key, Quantity = g.Count()});    

     return students; 
    } 

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

धन्यवाद!

+0

कुछ सामान्य सलाह: जब तक आप अधिक अनुभव प्राप्त वर का उपयोग बंद । यदि आपने 'IQueryable = (से ... 'का उपयोग करने का प्रयास किया था, तो आप समस्या पर बहुत तेजी से शून्य हो गए थे। –

उत्तर

4

अपने Student प्रकार बदलें इस तरह देखने के लिए

var students = from s in db.Students 
       group s by s.Name into g 
       select new Student { 
        Name = g.Key, 
        Quantity = g.Count() }; 

आपकी विधि IQueryable<Student> लौटाती है लेकिन आप वर्तमान में अनुमानित अनाम प्रकार के IQueryable<T> लौट रहे हैं।

आप प्रकार String के Name संपत्ति के लिए अपने Student प्रकार refactor और फिर अभिव्यक्ति से अपने Student प्रकार की नई उदाहरणों परियोजना ताकि आपके अभिव्यक्ति की वापसी प्रकार अपनी पद्धति की वापसी प्रकार से मेल खाएगी की जरूरत है।

+0

यह एक बग को ठीक करने के लिए" refactoring "नहीं है।और छात्र जिसने इसे ऊपर परिभाषित किया है, उसका नाम है, क्योंकि यह एक आंशिक वर्ग है जो उसके लिंक ऑब्जेक्ट से विस्तारित है जिसमें नाम और आईडी है। अब मात्रा बढ़ाने के लिए छात्र को विस्तारित करना निश्चित रूप से संदिग्ध है लेकिन .... –

+0

क्या मात्रा वर्ग जोड़ने के लिए छात्र वर्ग का विस्तार करना बुरा विचार है? मेरे पास छात्र के लिए डेटाबेस में मात्रा कॉलम नहीं है। मैं अपने ऑब्जेक्ट में छात्र ऑब्जेक्ट्स की एक सूची वापस करना चाहता हूं (जो छात्र ऑब्जेक्ट को विरासत में लेता है) मैं आसानी से मात्रा प्रदर्शित कर सकता हूं। क्या ऐसा करने का एक अलग/बेहतर तरीका है? – hanesjw

+0

हां, यह एक बुरा विचार है - मैं कोड को देख रहा था, न कि पूरी तस्वीर। –

2

समस्या यह है कि आप छात्रों को वापस नहीं कर रहे हैं - आप अपने फ़ंक्शन से एक अनाम प्रकार वापस करने का प्रयास कर रहे हैं। इसकी अनुमति नहीं है।

एक वर्ग अपने परिणाम का प्रतिनिधित्व करते हैं और अपने प्रश्न में new MyClass { ... } बजाय new { ... } उपयोग करने के लिए IQueryable<MyClass> बजाय IQueryable<Student> वापस जाने के लिए विधि बनाएँ, और बदल जाते हैं।

उदाहरण के लिए आप StudentNameAndResults नामक कक्षा बना सकते हैं।

class StudentNameAndResults 
{ 
    public string Name { get; set; } 
    public int Quantity { get; set; } 
} 

वैकल्पिक रूप से, आप परिणाम को एक शब्दकोश या आईग्रुपिंग के आईन्यूमेरेबल के रूप में वापस कर सकते हैं। उदाहरण के लिए:

public IDictionary<string, int> FindStudentsDistinctWithQuantity() 
{ 
    Database db = new Database(); 
    var students= (from s in db.Students 
       group s by s.Name into g 
       select new {Name = g.Key, Quantity = g.Count()}); 

    return students.ToDictionary(s => s.Name, s => s.Quantity); 
} 

इसके अलावा, संपत्ति आपके द्वारा बनाए गए पूर्व सी # 3.0 दिनों से विस्तृत सिंटैक्स का उपयोग कर रहा है। इस तरह देखने के लिए

public partial class Student 
{ 
    public Int32 Quantity { get; set; } 
    public String Name { get; set; } 
} 

और आपकी क्वेरी:: अब आप auto-implemented properties उपयोग कर सकते हैं अगर आप किसी भी विशेष तर्क की जरूरत नहीं है:

public int Quantity { get; set; } 
1
var students= (from s in db.Students 
        group s by s.Name into g 
        select new {Name = g.Key, Quantity = g.Count()}); 

यह एक अनाम प्रकार है, IQueryable<Student> नहीं। या तो आप System.Object वापस जाने के लिए की जरूरत है, या आप IQueryable<Student> वापस जाने के लिए इस प्रकार की आवश्यकता है ...

return from s in db.Students 
     group s by s.Name into g 
     select new Student{Name = g.Key, Quantity = g.Count()}; 

कहाँ छात्र initializtion में इस्तेमाल गुणों को परिभाषित करता।

+0

जबकि आप किसी अज्ञात प्रकार को System.Object के रूप में वापस कर सकते हैं, यह बहुत मदद नहीं करता है क्योंकि आप फ़ील्ड का उपयोग नहीं कर सकते हैं जब तक कि आप इसे सही उप प्रकार पर नहीं डालते, और आप नहीं जानते कि वह प्रकार क्या है। मैं ऐसा करने की सिफारिश नहीं करता। –

2

select new कीवर्ड डेटा के रूप में बदलने के लिए उत्पन्न कर रहे हैं, जिसका मतलब है LINQ क्वेरी एक IQueryable < छात्र > नहीं लौटेगा, बल्कि एक गुमनाम प्रकार युक्त "नाम" और "मात्रा" गुण। यदि आप किसी अज्ञात व्यक्ति के बजाय एक ठोस प्रकार को वापस करने के लिए इसे बदलते हैं तो आप इच्छित फॉर्म में डेटा पुनर्प्राप्त करने में सक्षम होंगे।

public class StudentGrouping { 
    public string Name { get; set; } 
    public int Quantity { get; set; } 
} 

public IQueryable<StudentGrouping> FindStudentsDistinctWithQuantity() 
{ 
    /*SELECT Name, COUNT(Name) AS Quantity 
    FROM Student 
    GROUP BY Name*/ 

    var students= (from s in db.Students 
       group s by s.Name into g 
       select new StudentGrouping { 
        Name = g.Key, 
        Quantity = g.Count() 
       }).AsQueryable();    

    return students; 
} 
+0

अंत में उस ASQueryable() के बारे में निश्चित नहीं है- क्या यह काम करेगा? –

2

आपका फ़ंक्शन छात्र

public IQueryable<Student> FindStudentsDistinctWithQuantity(){ ... } 

लेकिन अपने LINQ क्वेरी एक नए प्रकार है कि एक नाम और एक इंट (गणना)

   >>> select new {Name = g.Key, Quantity = g.Count()});    

नए छात्र का चयन {y-कोशिश शामिल रिटर्न नाम = जी। के, मात्रा = जी। गणना()}

1

आप अपने linq क्वेरी में एक प्रक्षेपण कर रहे हैं। यदि आप कर्सर को var students बनाम बनाम बनाते हैं तो आप इसे एक अनाम प्रकार का संग्रह देखेंगे।

आप एक IQueryabley<Student> आपको बस इतना करना वापस जाने के लिए चाहते हैं:

var students= from s in db.Students 
        group s by s.Name into g 
        select s.Key; 

कोई रास्ता नहीं बाहर तरीकों गुमनाम प्रकार आप अपने पिछले उदाहरण में बनाया है के बारे में पता कर सकते हैं नहीं है, इसलिए आप नहीं कर सकेंगे एक टाइप संग्रह को वापस करने के लिए।

var students = FindStudentsDistinctWithQuantity(); 
var namesAndQunatity = from s in students select new {s.Name, s.Quantity}; 
+0

मुझे लगता है कि समस्या यह है कि 'छात्र' के पास डेटाबेस में' मात्रा 'नहीं है और वह इसे कक्षा में जोड़ने और इसे इस क्वेरी के अंदर सेट करने का प्रयास कर रहा है। तो यदि आपने अपना सुझाव इस्तेमाल किया है, तो मुझे लगता है कि 'मात्रा' हमेशा 0 पर सेट की जाएगी। –

2

विधि द्वारा दिया गया मान संबंधों:

विधि मैं सुझाव आप अभी भी बाद में अपने विधि की वापसी मूल्य पर एक प्रक्षेपण करने के लिए, के बाद से IQueryable पहले गणन तक composable है में सक्षम हो जाएगा के साथ

"students" संग्रह IQueryable<Student> पर ... लेकिन लिंक अभिव्यक्ति IQueryable<some anonymous type> बना रही है, और दोनों के बीच कोई रूपांतरण नहीं है।

आप एक बच्चे को अपने चुनिंदा हिस्से को संशोधित होने के लिए आगे कदम प्राप्त कर सकते हैं:

select new Student() {....} 

उम्मीद है कि इस मदद करता है,

टायलर

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