अनुक्रम में कोई मेल खाता तत्व नहीं है


112

मेरे पास एक asp.net एप्लिकेशन है जिसमें मैं डेटा हेरफेर के लिए linq का उपयोग कर रहा हूं। दौड़ते समय, मुझे अपवाद मिलता है "अनुक्रम में कोई मिलान तत्व नहीं है"।

if (_lstAcl.Documents.Count > 0)
{
    for (i = 0; i <= _lstAcl.Documents.Count - 1; i++)
    {
        string id = _lstAcl.Documents[i].ID.ToString();                           
        var documentRow = _dsACL.Documents.First(o => o.ID == id);
        if (documentRow !=null)
        {

            _lstAcl.Documents[i].Read = documentRow.Read;
            _lstAcl.Documents[i].ReadRule = documentRow.ReadRule;

            _lstAcl.Documents[i].Create= documentRow.Create;
            _lstAcl.Documents[i].CreateRule = documentRow.CreateRule;

            _lstAcl.Documents[i].Update = documentRow.Update;
            _lstAcl.Documents[i].UpdateRule = documentRow.UpdateRule;

            _lstAcl.Documents[i].Delete = documentRow.Delete;
            _lstAcl.Documents[i].DeleteRule = documentRow.DeleteRule;
        }
    }
}

जवाबों:


220

खैर, मुझे उम्मीद है कि यह यह रेखा है जो अपवाद को फेंक रही है:

var documentRow = _dsACL.Documents.First(o => o.ID == id)

First()यदि कोई मेल खाने वाला तत्व नहीं मिल रहा है तो एक अपवाद को फेंक देंगे। यह देखते हुए कि आप तुरंत बाद शून्य के लिए परीक्षण कर रहे हैं, ऐसा लगता है कि आप चाहते हैं FirstOrDefault(), जो तत्व प्रकार के लिए डिफ़ॉल्ट मान लौटाता है (जो संदर्भ प्रकारों के लिए शून्य है) यदि कोई मिलान आइटम नहीं मिले:

var documentRow = _dsACL.Documents.FirstOrDefault(o => o.ID == id)

कुछ स्थितियों में विचार करने के अन्य विकल्प हैं Single()(जब आप मानते हैं कि वास्तव में एक मिलान तत्व है) और SingleOrDefault()(जब आप मानते हैं कि वास्तव में एक या शून्य मिलान तत्व हैं)। मुझे संदेह है कि FirstOrDefaultइस विशेष मामले में सबसे अच्छा विकल्प है, लेकिन यह दूसरों के बारे में वैसे भी जानने लायक है।

दूसरी ओर, ऐसा लगता है कि आप वास्तव में पहली जगह में शामिल होने से बेहतर हो सकते हैं। यदि आपको इस बात की परवाह नहीं थी कि यह आपके द्वारा उपयोग किए जा सकने वाले सभी मैचों (केवल पहले के बजाय) को करेगा:

var query = from target in _lstAcl.Documents
            join source in _dsAcl.Document
            where source.ID.ToString() equals target.ID
            select new { source, target };
foreach (var pair in query)
{
    target.Read = source.Read;
    target.ReadRule = source.ReadRule;
    // etc
}

यह सरल और अधिक कुशल IMO है।

यहां तक ​​कि अगर आप पाश रखने का फैसला करते हैं, तो मेरे पास कुछ सुझाव हैं:

  • बाहरी से छुटकारा पाएं if। आपको इसकी आवश्यकता नहीं है, जैसे कि गणना शून्य है क्योंकि लूप बॉडी कभी निष्पादित नहीं होगी
  • छोरों के लिए विशेष ऊपरी सीमा का उपयोग करें - वे C # में अधिक मुहावरेदार हैं:

    for (i = 0; i < _lstAcl.Documents.Count; i++)
  • आम सबटेक्शन्स को हटा दें:

    var target = _lstAcl.Documents[i];
    // Now use target for the rest of the loop body
  • जहां संभव हो foreachइसके बजाय forशुरू करने के लिए उपयोग करें :

    foreach (var target in _lstAcl.Documents)

39

FirstOrDefault का उपयोग करें । पहले कभी भी अशक्त नहीं लौटेगा - यदि यह एक मेल तत्व नहीं मिल सकता है तो यह आपके द्वारा देखे जा रहे अपवाद को फेंक देता है।

_dsACL.Documents.FirstOrDefault(o => o.ID == id);

19
बस थोड़ा स्पष्ट करने के लिए - पहले सामान्य रूप से अशक्त लौट सकता है , यदि आपका विधेय अशक्त मूल्यों से मेल खाता है। यह बस यहाँ अशक्त नहीं लौट सकता है, क्योंकि o.IDअशक्त मान पर NullReferenceException को फेंक देगा।
जॉन स्कीट

11

MSDN लाइब्रेरी से:

First<TSource>(IEnumerable<TSource>)विधि एक अपवाद फेंकता है तो स्रोत कोई तत्व शामिल हैं। स्रोत अनुक्रम खाली होने पर डिफ़ॉल्ट मान वापस करने के लिए, FirstOrDefaultविधि का उपयोग करें ।


0

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


-4

शायद पहले () से पहले कहां () का उपयोग करने से आपको मदद मिल सकती है, क्योंकि इस मामले में मेरी समस्या हल हो गई है।

var documentRow = _dsACL.Documents.Where(o => o.ID == id).FirstOrDefault();

3
क्या वास्तव में यहाँ आपकी मदद की गई है। .FirstOrDefault () के बजाय। ) समान होगा।
pwdst

@pwdst उस स्थिति का उपयोग करते हुए जहां खंड में और फिर FirstOrDefault बिना किसी लंबोदर अभिव्यक्ति के।
एल्नाज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.