जवाबों:
मैं जानता हूँ कि दूसरों लिखा है तुम क्यों एक या अन्य उपयोग करें, लेकिन मैंने सोचा कि मैं उदाहरण देकर स्पष्ट करना चाहते हैं आप इसे क्यों, जब आप का उपयोग नहीं करना चाहिए मतलब अन्य।
नोट: मेरे कोड में, मैं आमतौर पर उपयोग करूंगा FirstOrDefault()
और SingleOrDefault()
यह एक अलग सवाल है।
उदाहरण के लिए, एक मेज जो Customers
विभिन्न भाषाओं में एक समग्र कुंजी ( ID
, Lang
) का उपयोग करके संग्रहीत करता है :
DBContext db = new DBContext();
Customer customer = db.Customers.Where( c=> c.ID == 5 ).First();
ऊपर दिया गया यह कोड एक संभावित लॉजिक एरर (ट्रेस करना मुश्किल) पेश करता है। यह एक से अधिक रिकॉर्ड लौटाएगा (यह मानते हुए कि आपके पास कई भाषाओं में ग्राहक का रिकॉर्ड है) लेकिन यह हमेशा केवल पहला ही लौटाएगा ... जो कभी-कभी काम कर सकता है ... लेकिन अन्य नहीं। यह अप्रत्याशित है।
चूंकि आपका इरादा किसी एकल Customer
उपयोग को वापस करने का है Single()
;
निम्नलिखित एक अपवाद फेंक देगा (जो इस मामले में आप चाहते हैं):
DBContext db = new DBContext();
Customer customer = db.Customers.Where( c=> c.ID == 5 ).Single();
फिर, आप बस अपने आप को माथे पर मारते हैं और अपने आप से कहते हैं ... ओओपीएस! मैं भाषा क्षेत्र भूल गया! निम्नलिखित सही संस्करण है:
DBContext db = new DBContext();
Customer customer = db.Customers.Where( c=> c.ID == 5 && c.Lang == "en" ).Single();
First()
निम्नलिखित परिदृश्य में उपयोगी है:
DBContext db = new DBContext();
NewsItem newsitem = db.NewsItems.OrderByDescending( n => n.AddedDate ).First();
यह वन ऑब्जेक्ट लौटाएगा, और जब से आप छँटाई का उपयोग कर रहे हैं, यह सबसे हालिया रिकॉर्ड होगा जो वापस आ गया है।
Single()
जब आपको लगता है कि इसका उपयोग करना चाहिए स्पष्ट रूप से हमेशा 1 रिकॉर्ड वापस करना चाहिए तो आपको तर्क त्रुटियों से बचने में मदद मिलेगी।
customers.Where(predicate).Single()
customers.Single(predicate)
?
यदि यह मापदंड से मेल खाते एक से अधिक रिकॉर्ड पाता है, तो एकल अपवाद फेंक देगा। पहले हमेशा सूची से पहला रिकॉर्ड चुनेंगे। यदि क्वेरी सिर्फ 1 रिकॉर्ड लौटाती है, तो आप साथ जा सकते हैं First()
।
InvalidOperationException
यदि संग्रह खाली है तो दोनों अपवाद छोड़ देंगे । वैकल्पिक रूप से आप उपयोग कर सकते हैं SingleOrDefault()
। यदि सूची खाली है, तो यह अपवाद नहीं फेंकेगा
एक()
क्वेरी का एकल विशिष्ट तत्व देता है
जब उपयोग करें : यदि ठीक 1 तत्व अपेक्षित है; नहीं 0 या 1 से अधिक। यदि सूची खाली है या एक से अधिक तत्व हैं, तो यह एक अपवाद फेंक देगा "अनुक्रम में एक से अधिक तत्व हैं"
SingleOrDefault ()
यदि कोई परिणाम नहीं मिला, तो क्वेरी का एक विशिष्ट तत्व या डिफ़ॉल्ट मान लौटाता है
जब उपयोग करें : जब 0 या 1 तत्व अपेक्षित हों। यदि सूची में 2 या अधिक आइटम हैं, तो यह एक अपवाद को फेंक देगा।
प्रथम()
कई परिणामों के साथ क्वेरी का पहला तत्व देता है।
जब उपयोग करें : जब 1 या अधिक तत्वों की उम्मीद की जाती है और आप केवल पहले चाहते हैं। यदि सूची में कोई तत्व नहीं है तो यह एक अपवाद को फेंक देगा।
FirstOrDefault ()
सूची का पहला तत्व किसी भी राशि के तत्वों के साथ लौटाता है, या सूची खाली होने पर एक डिफ़ॉल्ट मान।
जब उपयोग करें : जब कई तत्वों की उम्मीद की जाती है और आप केवल पहले चाहते हैं। या सूची खाली है और आप निर्दिष्ट प्रकार के लिए एक डिफ़ॉल्ट मान चाहते हैं, जैसा कि
default(MyObjectType)
। उदाहरण के लिए: यदि सूची प्रकारlist<int>
यह सूची से पहला नंबर लौटाएगा या यदि सूची खाली है तो 0। यदि यह हैlist<string>
, तो यह सूची से पहला स्ट्रिंग लौटाएगा या सूची रिक्त होने पर रिक्त होगा।
First
तब कर सकते हैं जब 1 या अधिक तत्वों की अपेक्षा की जाती है , न केवल "1 से अधिक", और FirstOrDefault
किसी भी राशि के तत्वों के साथ।
इन दोनों विधियों के बीच एक सूक्ष्म, शब्दार्थ भेद है।
Single
एक अनुक्रम से पहले (और केवल) तत्व को पुनः प्राप्त करने के लिए उपयोग करें जिसमें एक तत्व होना चाहिए और अधिक नहीं। यदि अनुक्रम में तत्व से अधिक है, तो आपके आह्वान का Single
अपवाद एक अपवाद होगा क्योंकि आपने संकेत दिया था कि केवल एक तत्व होना चाहिए।
First
पहले तत्व को एक अनुक्रम से प्राप्त करने के लिए उपयोग करें जिसमें किसी भी संख्या में तत्व हो सकते हैं। यदि अनुक्रम में तत्व से अधिक है, तो आपके आह्वान का First
अपवाद अपवाद नहीं होगा क्योंकि आपने संकेत दिया था कि आपको केवल अनुक्रम में पहले तत्व की आवश्यकता है और अधिक मौजूद होने पर परवाह न करें।
यदि अनुक्रम में कोई तत्व नहीं है, तो दोनों विधि कॉल अपवादों को फेंक देंगे क्योंकि दोनों विधियाँ कम से कम एक तत्व मौजूद होने की उम्मीद करती हैं।
यदि आप विशेष रूप से इस घटना में एक अपवाद नहीं चाहते हैं कि एक से अधिक वस्तु, उपयोग होFirst()
।
दोनों कुशल हैं, पहले आइटम ले लो। First()
यह थोड़ा और अधिक कुशल है क्योंकि यह देखने के लिए कि कोई दूसरा आइटम है या नहीं, यह देखने के लिए परेशान नहीं करता है।
एकमात्र अंतर यह है कि Single()
उम्मीद है कि शुरू करने के लिए गणना में केवल एक आइटम होगा, और एक से अधिक होने पर अपवाद फेंक देगा। यदि आप विशेष रूप से इस मामले में एक अपवाद चाहते हैं, .Single()
तो आप उपयोग करते हैं ।
अगर मुझे याद है, तो सिंगल () चेक करता है कि पहले एक के बाद कोई दूसरा तत्व है (और यदि ऐसा है तो अपवाद छोड़ देता है), जबकि First () मिलने के बाद रुक जाता है। अनुक्रम खाली होने पर दोनों एक अपवाद को फेंक देते हैं।
व्यक्तिगत रूप से, मैं हमेशा फर्स्ट () का उपयोग करता हूं।
Peformance के बारे में: एक सहकर्मी और मैं सिंगल बनाम फ़र्स्ट (या SingleOrDefault vs FirstOrDefault) के प्रदर्शन पर चर्चा कर रहे थे, और मैं इस बात के लिए बहस कर रहा था कि फ़र्स्ट (या फ़र्स्टऑर्डफ़ॉल्ट) और तेज़ हो जाएगा और प्रदर्शन में सुधार होगा (मैं अपना ऐप बनाने के बारे में हूँ) और तेज़ दौड़ें)।
मैंने स्टैक ओवरफ्लो पर कई पोस्ट पढ़ी हैं जो इस पर बहस करते हैं। कुछ का कहना है कि सिंगल के बजाय फर्स्ट का उपयोग करके छोटे प्रदर्शन लाभ हैं। ऐसा इसलिए है क्योंकि पहले केवल पहली वस्तु को लौटाएगा, जबकि एकल को यह सुनिश्चित करने के लिए सभी परिणामों को स्कैन करना होगा कि कोई डुप्लिकेट नहीं है (यानी: यदि यह तालिका की पहली पंक्ति में आइटम मिला, तो यह अभी भी हर दूसरी पंक्ति को स्कैन करेगा सुनिश्चित करें कि उस स्थिति से मेल खाने वाला दूसरा मूल्य नहीं है जो फिर एक त्रुटि फेंक देगा)। मैंने महसूस किया कि मैं "सिंगल" की तुलना में "फर्स्ट" तेज होने के साथ ठोस आधार पर था, इसलिए मैंने इसे साबित करने के लिए सेट किया और बहस को आराम देने के लिए रखा।
मैंने अपने डेटाबेस में एक परीक्षण सेट किया और ID UniqueIdentifier विदेशी UniqueIdentifier Info nvarchar (50) की 100 पंक्तियों को जोड़ दिया (संख्याओं की संख्या "0" से "999,9999"
मैंने डेटा लोड किया और आईडी को प्राथमिक कुंजी फ़ील्ड के रूप में सेट किया।
LinqPad का उपयोग करना, मेरा लक्ष्य यह दिखाना था कि यदि आपने सिंगल का उपयोग करते हुए 'फॉरेन' या 'इंफो' पर कोई मूल्य खोजा, तो यह फर्स्ट का उपयोग करने की तुलना में बहुत बुरा होगा।
मुझे मिले परिणामों की व्याख्या नहीं कर सकता। लगभग हर मामले में सिंगल या सिंगलऑर्फ़ॉल्ट का उपयोग करना थोड़ा तेज़ था। यह मेरे लिए कोई तार्किक अर्थ नहीं रखता है, लेकिन मैं इसे साझा करना चाहता था।
Ex: मैंने निम्नलिखित प्रश्नों का उपयोग किया:
var q = TestTables.First(x=>x.Info == "314638") ;
//Vs.
Var q = TestTables.Single(x=>x.Info =="314638") ; //(this was slightly faster to my surprise)
मैंने 'विदेशी' कुंजी क्षेत्र पर समान प्रश्नों की कोशिश की, जो यह सोचकर अनुक्रमित नहीं था कि पहले साबित होगा, लेकिन सिंगल हमेशा मेरे परीक्षणों में थोड़ा तेज था।
वे भिन्न हैं। दोनों यह कहते हैं कि परिणाम सेट खाली नहीं है, लेकिन एकल यह भी दावा करता है कि 1 से अधिक परिणाम नहीं है। मैं व्यक्तिगत रूप से उन मामलों में सिंगल का उपयोग करता हूं जहां मुझे केवल 1 परिणाम होने की उम्मीद है क्योंकि 1 से अधिक परिणाम प्राप्त करना एक त्रुटि है और शायद इस तरह का व्यवहार किया जाना चाहिए।
आप अंतर प्राप्त करने के लिए सरल उदाहरण की कोशिश कर सकते हैं। अपवाद को पंक्ति 3 पर फेंक दिया जाएगा;
List<int> records = new List<int>{1,1,3,4,5,6};
var record = records.First(x => x == 1);
record = records.Single(x => x == 1);
कर्मचारी इकाई में रिकॉर्ड:
Employeeid = 1
: इस आईडी के साथ केवल एक कर्मचारी
Firstname = Robert
: इस नाम के एक से अधिक कर्मचारी
Employeeid = 10
: इस आईडी वाला कोई कर्मचारी नहीं
अब यह समझना आवश्यक है कि विस्तार से क्या Single()
और क्या First()
मतलब है।
एक()
सिंगल () एक एकल रिकॉर्ड को वापस करने के लिए उपयोग किया जाता है, जो विशिष्ट रूप से एक तालिका में मौजूद है, इसलिए नीचे दी गई क्वेरी कर्मचारी को वापस कर देगी, employeed =1
क्योंकि हमारे पास केवल एक कर्मचारी है जिसका Employeed
1. है। यदि हमारे पास दो रिकॉर्ड हैं, EmployeeId = 1
तो यह एक त्रुटि फेंकता है (देखें) दूसरी क्वेरी में नीचे त्रुटि जहां हम एक उदाहरण के लिए उपयोग कर रहे हैं Firstname
।
Employee.Single(e => e.Employeeid == 1)
उपरोक्त एक एकल रिकॉर्ड लौटाएगा, जिसमें 1 है employeeId
Employee.Single(e => e.Firstname == "Robert")
उपरोक्त एक अपवाद को फेंक देगा क्योंकि मल्टीपल रिकॉर्ड के लिए तालिका में हैं FirstName='Robert'
। अपवाद होगा
InvalidOperationException: अनुक्रम में एक से अधिक तत्व होते हैं
Employee.Single(e => e.Employeeid == 10)
यह, फिर से, एक अपवाद को फेंक देगा क्योंकि आईडी = 10 के लिए कोई रिकॉर्ड मौजूद नहीं है। अपवाद होगा
InvalidOperationException: अनुक्रम में कोई तत्व नहीं हैं।
क्योंकि EmployeeId = 10
यह अशक्त हो जाएगा, लेकिन जैसा कि हम उपयोग कर रहे हैं Single()
वह एक त्रुटि फेंक देगा। अशक्त त्रुटि को संभालने के लिए हमें उपयोग करना चाहिए SingleOrDefault()
।
प्रथम()
पहले () कई अभिलेखों से रिटर्न इसी क्रम में क्रमबद्ध क्रमबद्ध क्रमबद्ध होते हैं, birthdate
इसलिए यह 'रॉबर्ट' जो सबसे पुराना है, लौटाएगा।
Employee.OrderBy(e => e. Birthdate)
.First(e => e.Firstname == "Robert")
ऊपर को DOB के अनुसार सबसे पुराना, रॉबर्ट लौटना चाहिए।
Employee.OrderBy(e => e. Birthdate)
.First(e => e.Employeeid == 10)
ऊपर एक अपवाद फेंक देंगे क्योंकि आईडी = 10 के लिए कोई रिकॉर्ड मौजूद नहीं है। एक अशक्त अपवाद से बचने के लिए हमें इसके FirstOrDefault()
बजाय उपयोग करना चाहिए First()
।
नोट: हम केवल First()
/ Single()
जब हम पूरी तरह से सुनिश्चित कर सकते हैं कि यह एक शून्य मान नहीं लौटा सकता है।
दोनों कार्यों में SingleOrDefault () या FirstOrDefault () का उपयोग किया जाता है, जो एक शून्य अपवाद को संभाल लेगा, कोई रिकॉर्ड नहीं होने की स्थिति में यह अशक्त हो जाएगा।