c# अधिकतम या डिफ़ॉल्ट?
LINQ क्वेरी से अधिकतम मान प्राप्त करने का सबसे अच्छा तरीका क्या है जो कोई पंक्ति नहीं लौटा सकता है? अगर मैं बस करता हूँ
Dim x = (From y In context.MyTable _
Where y.MyField = value _
Select y.MyCounter).Max
जब कोई क्वेरी कोई पंक्ति नहीं लौटाती है तो मुझे एक त्रुटि मिलती है। मैं कर सकता था
Dim x = (From y In context.MyTable _
Where y.MyField = value _
Select y.MyCounter _
Order By MyCounter Descending).FirstOrDefault
लेकिन ऐसा लगता है कि इस तरह के एक सरल अनुरोध के लिए थोड़ा उलझन में है। क्या मुझे ऐसा करने का बेहतर तरीका याद आ रहा है?
अद्यतन: यहां पिछली कहानी है: मैं एक बच्चे की मेज से अगले योग्यता काउंटर को पुनः प्राप्त करने की कोशिश कर रहा हूं (विरासत प्रणाली, मुझे शुरू नहीं करें ...)। प्रत्येक रोगी के लिए पहली पात्रता पंक्ति हमेशा 1 होती है, दूसरा 2 होता है, आदि (जाहिर है यह बाल तालिका की प्राथमिक कुंजी नहीं है)। इसलिए, मैं एक रोगी के लिए अधिकतम मौजूदा काउंटर वैल्यू का चयन कर रहा हूं, और फिर एक नई पंक्ति बनाने के लिए इसमें 1 जोड़ रहा हूं। जब कोई मौजूदा बच्चा मूल्य नहीं होता है, तो मुझे 0 को वापस करने के लिए क्वेरी की आवश्यकता होती है (इसलिए 1 जोड़ना मुझे 1 का काउंटर वैल्यू देगा)। ध्यान दें कि मैं बाल पंक्तियों की कच्ची गिनती पर भरोसा नहीं करना चाहता हूं, अगर विरासत ऐप काउंटर मूल्यों (संभव) में अंतराल पेश करता है। प्रश्न को सामान्य बनाने की कोशिश करने के लिए मेरा बुरा।
आप जो पूछ रहे हैं उसके बारे में सोचें!
{1, 2, 3, -1, -2, -3} का अधिकतम स्पष्ट रूप से 3. अधिकतम {2} स्पष्ट रूप से 2 है। लेकिन खाली सेट का अधिकतम {} क्या है? जाहिर है कि यह एक अर्थहीन सवाल है। खाली सेट का अधिकतम बस परिभाषित नहीं किया गया है। उत्तर पाने का प्रयास करना गणितीय त्रुटि है। किसी भी सेट का अधिकतम स्वयं उस सेट में एक तत्व होना चाहिए। खाली सेट में कोई तत्व नहीं है, इसलिए दावा करना कि कुछ विशेष संख्या उस सेट के बिना सेट के अधिकतम है, वह गणितीय विरोधाभास है।
जैसे ही प्रोग्रामर अपवाद फेंकने के लिए कंप्यूटर के लिए सही व्यवहार करता है, जब प्रोग्रामर इसे शून्य से विभाजित करने के लिए कहता है, इसलिए कंप्यूटर के लिए अपवाद फेंकने के लिए यह सही व्यवहार है जब प्रोग्रामर इसे खाली सेट को अधिकतम करने के लिए कहता है। शून्य से डिवीजन, रिक्त सेट का अधिकतम भाग लेना, स्पैक्लरॉर्के को घुमाएं, और उड़ने वाले यूनिकॉर्न को नेवरलैंड में सवार करना सभी अर्थहीन, असंभव, अपरिभाषित हैं।
अब, आप वास्तव में क्या करना चाहते हैं?
int max = list.Any() ? list.Max(i => i.MyCounter) : 0;
यदि सूची में कोई तत्व है (यानी खाली नहीं), तो यह अधिकतम माईकॉन्टर फ़ील्ड लेगा, अन्यथा 0 वापस आ जाएगा।
मुझे लगता है कि समस्या यह है कि जब आप क्वेरी का कोई परिणाम नहीं लेते हैं तो आप क्या करना चाहते हैं। यदि यह एक असाधारण मामला है तो मैं क्वेरी को एक कोशिश / पकड़ ब्लॉक में लपेटूंगा और मानक क्वेरी उत्पन्न करने वाले अपवाद को संभालेगा। यदि क्वेरी ठीक से कोई परिणाम नहीं लौटाती है, तो आपको यह पता लगाना होगा कि आप उस मामले में क्या परिणाम चाहते हैं। यह हो सकता है कि @ डेविड का जवाब (या कुछ ऐसा ही काम करेगा)। यही है, यदि MAX हमेशा सकारात्मक होगा, तो सूची में ज्ञात "खराब" मान डालने के लिए पर्याप्त हो सकता है जो केवल तभी चुना जाएगा जब कोई परिणाम न हो। आम तौर पर, मैं एक ऐसी क्वेरी की अपेक्षा करता हूं जो अधिकतम डेटा प्राप्त करने के लिए अधिकतम डेटा प्राप्त कर रहा हो और मैं कोशिश / पकड़ मार्ग पर जाऊंगा अन्यथा आपको हमेशा यह जांचने के लिए मजबूर किया जाता है कि आपके द्वारा प्राप्त मूल्य सही है या नहीं। मैं बल्कि इतना असाधारण मामला प्राप्त मूल्य का उपयोग करने में सक्षम था।
Try
Dim x = (From y In context.MyTable _
Where y.MyField = value _
Select y.MyCounter).Max
... continue working with x ...
Catch ex As SqlException
... do error processing ...
End Try
देर से लिट, लेकिन मुझे एक ही चिंता थी ...
मूल कोड से अपने कोड को दोबारा दोहराएं, आप सेट एस के अधिकतम परिभाषित करना चाहते हैं
(From y In context.MyTable _
Where y.MyField = value _
Select y.MyCounter)
खाते में अपनी आखिरी टिप्पणी लेना
कहने का पर्याप्त कारण है कि मुझे पता है कि मुझे 0 चाहिए जब से चुनने के लिए कोई रिकॉर्ड नहीं है, जो निश्चित रूप से अंतिम समाधान पर असर डालता है
मैं आपकी समस्या को फिर से बदल सकता हूं: आप अधिकतम {0 + एस} चाहते हैं। और ऐसा लगता है कि कॉन्सैट के साथ प्रस्तावित समाधान अर्थात् सही है :-)
var max = new[]{0}
.Concat((From y In context.MyTable _
Where y.MyField = value _
Select y.MyCounter))
.Max();
बस हर किसी को यह जानने के लिए कि लिंक से इकाइयों का उपयोग कर रहा है ऊपर दिए गए तरीके काम नहीं करेंगे ...
यदि आप कुछ ऐसा करने की कोशिश करते हैं
var max = new[]{0}
.Concat((From y In context.MyTable _
Where y.MyField = value _
Select y.MyCounter))
.Max();
यह एक अपवाद फेंक देगा:
System.NotSupportedException: LINQ अभिव्यक्ति नोड प्रकार 'NewArrayInit' LINQ से इकाइयों में समर्थित नहीं है ..
मैं बस सुझाव दे रहा हूँ
(From y In context.MyTable _
Where y.MyField = value _
Select y.MyCounter))
.OrderByDescending(x=>x).FirstOrDefault());
और अगर आपकी सूची खाली है तो FirstOrDefault
0 वापस आ जाएगा।
decimal Max = (decimal?)(context.MyTable.Select(e => e.MyCounter).Max()) ?? 0;
मैंने MaxOrDefault
एक्सटेंशन विधि को MaxOrDefault
कर दिया है। इसके लिए बहुत कुछ नहीं है लेकिन इंटेलिसेंस में इसकी उपस्थिति एक उपयोगी अनुस्मारक है कि खाली अनुक्रम पर Max
अपवाद का कारण बन जाएगा। इसके अतिरिक्त, यदि आवश्यक हो तो विधि डिफ़ॉल्ट को निर्दिष्ट करने की अनुमति देती है।
public static TResult MaxOrDefault<TSource, TResult>(this
IQueryable<TSource> source, Expression<Func<TSource, TResult?>> selector,
TResult defaultValue = default (TResult)) where TResult : struct
{
return source.Max(selector) ?? defaultValue;
}
Id
नामित प्रकार के कॉलम या संपत्ति पर उपयोग Id
:
sequence.DefaultOrMax(s => (int?)s.Id);