एक आइटम का चयन करने के लिए Linq कोड


105

मैं खुद को इस तरह के बहुत से कोड लिख रहा हूं जो मेल खाता है एक आइटम का चयन करने के लिए

var item = (from x in Items where x.Id == 123 select x).First();

वहाँ ऐसा करने का एक क्लीनर तरीका है या यह संक्षिप्त है जैसा कि मैं प्राप्त करने जा रहा हूं?

संपादित करें: कहा जाना चाहिए "लाइनक सिंटैक्स का उपयोग करके क्लीनर तरीका"। मैं पहले से ही लैम्ब्डा सिंटैक्स के बारे में जानता था और ऐसा लगने लगा कि यह वास्तव में एकमात्र तरीका है। हालांकि मुझे कुछ उपयोगी जानकारी मिली, इसलिए सभी को धन्यवाद जिन्होंने उत्तर दिया।


5
व्यक्तिगत रूप से मैं बचता हूं Single()और SingleOrDefault()अगर मुझे पता है कि डेटा पहले से ही अद्वितीय है (उदाहरण के लिए एक डेटाबेस से जो कि बाधा है, आदि), क्योंकि Single()यह संभावित डुप्लिकेट को खोजने के लिए बाकी सूची को स्कैन करने के लिए मजबूर करता है, लेकिन यह मैं ही हूं। यदि आपको इस बिंदु पर अपनी विशिष्टता को लागू करने की आवश्यकता है Single(), तो परिवार का उपयोग करें , यदि नहीं, तो First()परिवार का उपयोग करें ।
जेम्स माइकल हरे

जवाबों:


176

निर्भर करता है कि आप linq क्वेरी सिंटैक्स को कितना पसंद करते हैं, आप सीधे एक्सटेंशन विधियों का उपयोग कर सकते हैं जैसे:

var item = Items.First(i => i.Id == 123);

और यदि आप कोई त्रुटि नहीं चाहते हैं यदि सूची खाली है, FirstOrDefaultतो तत्व प्रकार के लिए डिफ़ॉल्ट मान लौटाएं ( nullसंदर्भ प्रकारों के लिए):

var item = Items.FirstOrDefault(i => i.Id == 123);

if (item != null)
{
    // found it
}

Single()और SingleOrDefault()इसका उपयोग भी किया जा सकता है, लेकिन अगर आप डेटाबेस या किसी ऐसी चीज़ से पढ़ रहे हैं, जो पहले से ही विशिष्टता की गारंटी देता है तो मैं परेशान नहीं होता क्योंकि यह देखने के लिए सूची को स्कैन करना होगा कि क्या कोई डुप्लिकेट और थ्रो है। First()और FirstOrDefault()पहले मैच पर रोक, इसलिए वे अधिक कुशल हैं।

की First()और Single()परिवार, यहाँ है, जहां वे फेंक:

  • First() - अगर खाली / नहीं मिला तो फेंकता है, अगर नकल नहीं करता है
  • FirstOrDefault() - यदि खाली / नहीं मिला तो डिफ़ॉल्ट रूप से रिटर्न देता है, यदि डुप्लिकेट नहीं है तो फेंक देता है
  • Single() - यदि खाली / नहीं मिला तो फेंकता है, यदि डुप्लिकेट मौजूद है तो फेंकता है
  • SingleOrDefault() - यदि कोई डुप्लिकेट मौजूद है, तो खाली / न मिलने पर डिफ़ॉल्ट लौटाता है

1
मुझे लगता है कि आप वहाँ दो बराबर संकेत याद कर रहे हैं। होना चाहिएi.Id == 123
davehale23

18

FirstOrDefault या SingleOrDefault उपयोगी हो सकता है, यह आपके परिदृश्य पर निर्भर करता है, और क्या आप वहां शून्य या एक से अधिक मैचों को संभालना चाहते हैं:

FirstOrDefault: अनुक्रम का पहला तत्व, या कोई तत्व नहीं मिलने पर एक डिफ़ॉल्ट मान लौटाता है।

SingleOrDefault: यदि अनुक्रम खाली है, तो अनुक्रम का एकमात्र तत्व या डिफ़ॉल्ट मान लौटाता है; यदि अनुक्रम में एक से अधिक तत्व हैं, तो यह विधि एक अपवाद को फेंकती है

मुझे नहीं पता कि यह 'linq' में 'क्वेरी' से कैसे काम करता है लेकिन लैम्ब्डा सिंटैक्स में यह इस तरह दिखता है:

var item1 = Items.FirstOrDefault(x => x.Id == 123);
var item2 = Items.SingleOrDefault(x => x.Id == 123);

DB समय पर कौन सा सबसे अधिक कुशल है? अगर मेरे पास एक वर्चर होता तो मैं एक सटीक मैच चाहता था, लेकिन संभव है कि कोई नहीं हो सकता?
पियोट कुला

2
स्वीकार किए गए उत्तर इसे पूर्ण रूप से संबोधित करते हैं, लेकिन अनिवार्य रूप से FirstOrDefault जैसे ही एक मैच पाता है, लेकिन SingleOrDefault को पूरी सूची की जांच करनी चाहिए ताकि यह सुनिश्चित हो सके कि वास्तव में एक मैच है।
स्टुअर्ट

12

ये पसंदीदा तरीके हैं:

var item = Items.SingleOrDefault(x => x.Id == 123);

या

var item = Items.Single(x => x.Id == 123);

धन्यवाद - तो इस स्थिति में कोई लाइनक नोटेशन नहीं है और मुझे लैम्ब्डा का उपयोग करने की आवश्यकता है?
मिकी हॉगर्थ

वह बहुत बढिया है। मैंने वास्तव में लाइनक का बहुत उपयोग नहीं किया है, इसलिए मुझे यकीन नहीं है कि मैं इन तरीकों से भी अवगत था।
वेजोगे

1
एकल विधि जाँच करती है कि रिटर्न वैल्यू अद्वितीय है। इसलिए यदि आपका संग्रह बड़ा है तो इसमें बहुत समय लग सकता है। पहला तरीका सिर्फ पहले तत्व को लौटाता है जो विधेय से मेल खाता है।
meziantou

@wageoghe James 'का उत्तर linq का उपयोग नहीं करता है - एकल और SingleOrDefault विधियाँ IEnumable कार्यान्वयन का हिस्सा हैं।
मिकी हॉगर्थ

12

बस किसी के जीवन को आसान बनाने के लिए, lambda अभिव्यक्ति के साथ linq क्वेरी

(from x in Items where x.Id == 123 select x).FirstOrDefault();

इसमें SQL क्वेरी के साथ परिणाम होता select top (1)है।


9

इसे बेहतर तरीके से संघनित किया जा सकता है।

var item = Items.First(x => x.Id == 123);

आपकी क्वेरी वर्तमान में सभी परिणामों को एकत्र कर रही है (और वहाँ एक से अधिक हो सकता है) असंख्य के भीतर और फिर उस सेट से पहला लेने, आवश्यकता से अधिक काम कर रहा है।

एकल / SingleOrDefault सार्थक हैं, लेकिन केवल यदि आप पूरे संग्रह के माध्यम से पुनरावृति करना चाहते हैं और सत्यापित करते हैं कि मैच उस मैच को चुनने के अलावा अद्वितीय है। पहला / FirstOrDefault सिर्फ पहला मैच लेगा और छोड़ देगा, चाहे कितने भी डुप्लिकेट मौजूद हों।


4

आप एक्सटेंशन विधि सिंटैक्स का उपयोग कर सकते हैं:

var item = Items.Select(x => x.Id == 123).FirstOrDefault();

उसके अलावा, मुझे यकीन नहीं है कि आप अपने स्वयं के विशेष "फर्स्ट" और "फ़र्स्टऑर्डडेफ़ॉल्ट" एक्सटेंशन के तरीकों को लिखने के बिना कितना संक्षिप्त रूप प्राप्त कर सकते हैं।


मुझे नहीं लगता कि यह इच्छित व्यवहार है। यह चयन निर्देश रिटर्न (वास्तव में नहीं है, लेकिन यह रिटर्न के लिए चयन करता है) बूल का एक संग्रह, आइटम के प्रत्येक तत्व के लिए एक, जो आइटम के रूप में लौटा है, वह बस एक बूल बन जाता है। क्रिस हनन के समाधान का उपयोग करें
लियोनार्डो डागा

शायद आपका मतलब Whereविरोध के रूप में है Select, जो पहले ही कहा जा चुका है, लेकिन यह उत्तर गलत है। C # में परिणाम का चयन करें IEnumerable <bool> में परिवर्तन करता है, इसलिए आपको boolपहली आइटम के लिए मिल रहा हैx.Id == 123
bradlis7

2

मैं बताता हूँ कि मेरे लिए क्या काम किया है:

int id = int.Parse(insertItem.OwnerTableView.DataKeyValues[insertItem.ItemIndex]["id_usuario"].ToString());

var query = user.First(x => x.id_usuario == id);
tbUsername.Text = query.username;
tbEmail.Text = query.email;
tbPassword.Text = query.password;

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

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