अनुक्रम में एक से अधिक तत्व होते हैं


110

मैं Linq के माध्यम से "RhsTruck" प्रकार की सूची को हथियाने और उन्हें प्रदर्शित करने के लिए प्राप्त करने के साथ कुछ मुद्दे रख रहा हूं।

RhsTruck में सिर्फ उचित मेक, मॉडल, सीरियल आदि हैं ... RhsCustomer में CustomerName, CustomerAddress आदि गुण हैं ...

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

public RhsCustomer GetCustomer(string customerNumber)
{
    using (RhsEbsDataContext context = new RhsEbsDataContext() )
    {
        RhsCustomer rc = (from x in context.custmasts
                          where x.kcustnum == customerNumber
                          select new RhsCustomer()
                        {
                            CustomerName = x.custname,
                            CustomerAddress = x.custadd + ", " + x.custcity
                            CustomerPhone = x.custphone,
                            CustomerFax = x.custfax
                        }).SingleOrDefault();
        return rc;
    }
}

public List<RhsTruck> GetEquipmentOwned(RhsCustomer cust)
{
    using (RhsEbsDataContext context = new RhsEbsDataContext())
    {
        var trucks = (from m in context.mkpops
                      join c in context.custmasts
                        on m.kcustnum equals c.kcustnum
                      where m.kcustnum == cust.CustomerNumber
                      select new RhsTruck
                    {
                        Make = m.kmfg,
                        Model = m.kmodel,
                        Serial = m.kserialnum,
                        EquipID = m.kserialno1,
                        IsRental = false
                    }).ToList();
        return trucks;
    }
}

protected void Page_Load(object sender, EventArgs e)
{
    string testCustNum = Page.Request.QueryString["custnum"].ToString();

    RhsCustomerRepository rcrep = new RhsCustomerRepository();
    RhsCustomer rc = rcrep.GetCustomer(testCustNum);
    List<RhsTruck> trucks = rcrep.GetEquipmentOwned(rc);

    // I want to display the List into a Gridview w/auto-generated columns
    GridViewTrucks.DataSource = trucks;
    GridViewTrucks.DataBind();   
}

1
SQL टॉप () कुल फंक्शन के साथ <> का उपयोग करें ,.Take(1).SingleOrDefault();
Thein

जवाबों:


254

समस्या यह है कि आप उपयोग कर रहे हैं SingleOrDefault। यह विधि केवल तभी सफल होगी जब संग्रह में ठीक 0 या 1 तत्व हो। मेरा मानना ​​है कि आप खोज रहे हैं FirstOrDefaultजो संग्रह में कितने तत्व हैं, इससे कोई फर्क नहीं पड़ेगा।


8
केल्विन, उस मामले में आपको इस उत्तर को एक समाधान के रूप में स्वीकार करना चाहिए
देजन मिलिकिक

24
-1 "समस्या यह है कि आप SingleOrDefault का उपयोग कर रहे हैं" - मैं जो ओपी इकट्ठा कर सकता हूं वह एक ग्राहक आईडी की तलाश में है जो (मुझे लगता है) अद्वितीय होना चाहिए, इसलिए, SingleOrDefaultवास्तव में की तुलना में अधिक उपयुक्त है FirstOrDefault। इसके अलावा, इसने वास्तव में ओपी के डेटाबेस डिजाइन के साथ एक और अधिक गंभीर समस्या खड़ी कर दी है क्योंकि यह दर्शाता है कि एक ही आईडी के साथ 2 ग्राहकों को जोड़ना संभव है!
जेम्स

27
@ जेम्स, ओपी ने कहा कि मेरा उत्तर सही था और अपवाद में स्पष्ट रूप से कहा गया है कि संग्रह में एक से अधिक तत्व हैं जो SingleOrDefaultहमेशा काम करने से रोकता है। यह सच है कि यह हो सकता है यहाँ एक बेहतर डेटाबेस डिजाइन करने के लिए संभव हो सकता है लेकिन यह है कि ओपी और नहीं एक -1 एक जवाब पर पर एक टिप्पणी के रूप में और अधिक उपयुक्त लगता है।
जारेदपार

9
IMO की अंतर्निहित समस्या अंततः DB डिज़ाइन है क्योंकि यह दिखाता है कि 2 विशिष्ट ग्राहक ID को डेटाबेस में जोड़ा जा सकता है। SingleOrDefaultएक अपवाद फेंक रहा है क्योंकि विधि क्या अपेक्षा करता है और यह क्या खोज रहा है, के बीच एक असंगतता है। इसलिए यद्यपि आपका उत्तर अपवाद को रोकता है, मेरे लिए, यह वास्तव में उस समस्या का समाधान नहीं करता है जो "जेल से बाहर निकलना" कार्ड है इसलिए -1।
जेम्स

2
यह भ्रामक है! SingleOrDefaultतब का उपयोग तब होता है जब आप एक संग्रह की उम्मीद करते हैं कि आपके पास 0 या 1 आइटम है और आप हर बार ऐसा करना चाहते हैं ...
Achilles

23

SingleOrDefaultविधि Exceptionअनुक्रम में एक से अधिक तत्व होने पर फेंकता है।

जाहिर है, आपकी क्वेरी में GetCustomerएक से अधिक मिलान मिल रहे हैं। इसलिए आपको या तो अपनी क्वेरी को परिष्कृत करने की आवश्यकता होगी या, सबसे अधिक संभावना है, अपने डेटा की जांच करें कि आपको किसी दिए गए ग्राहक नंबर के लिए कई परिणाम क्यों मिल रहे हैं।


5
Use FirstOrDefault insted of SingleOrDefault..

SingleOrDefault कोई तत्व नहीं मिलने पर एक SINGLE तत्व या अशक्त देता है। यदि आपके Enumerable में 2 तत्व पाए जाते हैं तो यह आपके द्वारा देखे जा रहे अपवाद को फेंक देता है

FirstOrDefault उस FIRST तत्व को लौटाता है जिसे कोई तत्व नहीं मिला है या अशक्त है। इसलिए अगर वहाँ 2 तत्व हैं जो आपकी भविष्यवाणी से मेल खाते हैं तो दूसरे को अनदेखा कर दिया जाता है

   public int GetPackage(int id,int emp)
           {
             int getpackages=Convert.ToInt32(EmployerSubscriptionPackage.GetAllData().Where(x
   => x.SubscriptionPackageID ==`enter code here` id && x.EmployerID==emp ).FirstOrDefault().ID);
               return getpackages;
           }

 1. var EmployerId = Convert.ToInt32(Session["EmployerId"]);
               var getpackage = GetPackage(employerSubscription.ID, EmployerId);

1

FYI करें, यदि EF माइग्रेशन कॉन्फ़िगर किए बिना किसी भी परीक्षण प्रोजेक्ट में उदाहरण के लिए चलाने का प्रयास करता है, तो आपको यह त्रुटि भी हो सकती है।

घंटों पहले यह पता चला कि मुझे पता था कि यह किसी क्वेरी पर इर्रिटिंग कर रहा है, लेकिन, क्वेरी के कारण नहीं, बल्कि इसलिए कि जब माइग्रेशन डीबी बनाने की कोशिश करने के लिए किक किया गया था।


0

जैसा कि @Mehmet इंगित कर रहा है, यदि आपका परिणाम अधिक वापस आ रहा है तो 1 क्षरण तो आपको डेटा पर ध्यान देने की आवश्यकता है क्योंकि मुझे संदेह है कि इसका डिज़ाइन द्वारा नहीं है कि आपके पास एक कस्टमरनंबर साझा करने वाले ग्राहक हैं।

लेकिन इस बिंदु पर मैं आपको एक त्वरित अवलोकन देना चाहता था।

//success on 0 or 1 in the list, returns dafault() of whats in the list if 0
list.SingleOrDefault();
//success on 1 and only 1 in the list
list.Single();

//success on 0-n, returns first element in the list or default() if 0 
list.FirstOrDefault();
//success 1-n, returns the first element in the list
list.First();

//success on 0-n, returns first element in the list or default() if 0 
list.LastOrDefault();
//success 1-n, returns the last element in the list
list.Last();

अधिक Linq अभिव्यक्तियों के लिए System.Linq.Expressions पर एक नज़र है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.