यदि खाली क्वेरी अधिकतम मान


175

मेरे पास यह प्रश्न है:

int maxShoeSize = Workers
    .Where(x => x.CompanyId == 8)
    .Max(x => x.ShoeSize);

maxShoeSizeयदि कंपनी 8 में कोई श्रमिक नहीं है तो क्या होगा ?

अद्यतन:
मैं 0 पाने के लिए क्वेरी को कैसे बदल सकता हूं और अपवाद नहीं?


Naor: क्या आपने LINQPad के बारे में सुना है?
मिच गेहूं

3
मुझे समझ नहीं आ रहा है कि आप यह क्यों पूछेंगे कि 'क्या होगा maxShoeSize?' अगर आपने पहले ही इसे आज़मा लिया था।
jwg

@jwg: मुझे लगता है कि मैं यह देखना चाहता था कि क्या आपको जवाब पता है :) आखिरकार मुझे जो मैंने पूछा वह करने का एक बेहतर तरीका है और मेरा यही मतलब है।
नौ

@ नहीं, यह एक अनुमान लगाने का खेल नहीं है। मैं मूल प्रश्न को भी रद्द कर दूंगा। अगर आपको पता है तो इसका जवाब हमें दें अन्यथा आप आलसी दिखते हैं। बस अब मैं एक ही सवाल करने वाला था और मैं अपवाद संदेश सहित सभी जानकारी तैयार करता हूं।
जुआन कार्लोस ओरोपेज़ा

जवाबों:


298
int maxShoeSize = Workers.Where(x => x.CompanyId == 8)
                         .Select(x => x.ShoeSize)
                         .DefaultIfEmpty(0)
                         .Max();

शून्य DefaultIfEmptyआवश्यक नहीं है।


वर्क्स :) लेकिन मेरे कोड पर DefaultIfEmpty में शून्य आवश्यक था।
कार्लोस टेनोरियो पेरेज़

1
प्रश्न के पहले भाग के बारे में, जिसका यहां पूरी तरह से उत्तर नहीं दिया गया है: आधिकारिक दस्तावेज के अनुसार , यदि रिक्त अनुक्रम का सामान्य प्रकार एक संदर्भ प्रकार है, तो आप अशक्त हो जाते हैं। अन्यथा, इस प्रश्न के अनुसार , Max()खाली अनुक्रम पर कॉल करने से त्रुटि होती है।
रायमुंड क्रमर

59

मुझे पता है कि यह एक पुराना सवाल है और स्वीकृत उत्तर काम करता है, लेकिन इस सवाल ने मेरे सवाल का जवाब दिया कि क्या इस तरह के खाली सेट का अपवाद होगा या default(int)परिणाम।

हालाँकि, स्वीकृत जवाब, जबकि यह काम करता है, आदर्श समाधान IMHO नहीं है, जो यहाँ नहीं दिया गया है। इस प्रकार मैं इसे अपने स्वयं के उत्तर में प्रदान कर रहा हूं जो किसी को भी इसके लाभ के लिए देख रहा है।

ओपी का मूल कोड था:

int maxShoeSize = Workers.Where(x => x.CompanyId == 8).Max(x => x.ShoeSize);

इसे मैं अपवादों को रोकने और डिफ़ॉल्ट परिणाम प्रदान करने के लिए लिखूंगा:

int maxShoeSize = Workers.Where(x => x.CompanyId == 8).Max(x => x.ShoeSize as int?) ?? 0;

यह Maxफ़ंक्शन के रिटर्न प्रकार का कारण बनता है int?, जो nullपरिणाम की अनुमति देता है और फिर परिणाम के साथ ??बदलता है । null0


संपादित करें
केवल टिप्पणियों से कुछ स्पष्ट करने के लिए, एंटिटी फ्रेमवर्क वर्तमान में asकीवर्ड का समर्थन नहीं करता है , इसलिए ईएफ के साथ काम करते समय इसे लिखने का तरीका होगा:

int maxShoeSize = Workers.Where(x => x.CompanyId == 8).Max<[TypeOfWorkers], int?>(x => x.ShoeSize) ?? 0;

चूंकि [TypeOfWorkers]एक लंबा वर्ग नाम हो सकता है और लिखने के लिए थकाऊ है, इसलिए मैंने मदद करने के लिए एक विस्तार विधि जोड़ी है।

public static int MaxOrDefault<T>(this IQueryable<T> source, Expression<Func<T, int?>> selector, int nullValue = 0)
{
    return source.Max(selector) ?? nullValue;
}

यह केवल हैंडल int, लेकिन एक ही के लिए किया जा सकता है long, doubleया किसी भी अन्य मान प्रकार आप की जरूरत। इस विस्तार विधि का उपयोग करना बहुत सरल है, आप बस अपने चयनकर्ता फ़ंक्शन में पास होते हैं और वैकल्पिक रूप से शून्य के लिए उपयोग किए जाने वाले मान को शामिल करते हैं, जो कि 0. के लिए चूकता है। इसलिए उपरोक्त को फिर से लिखा जा सकता है:

int maxShoeSize = Workers.Where(x => x.CompanyId == 8).MaxOrDefault(x => x.ShoeSize);

उम्मीद है कि इससे लोगों को और भी मदद मिलेगी।


3
महान समाधान! अधिक लोकप्रिय DefaultIfEmptyजवाब केवल तभी अच्छा काम करता है जब Maxकोई मूल्यांकन नहीं कर रहा हो।
McGuireV10

@ McGuireV10 हाँ, मैं आमतौर पर Selectएक मध्यम व्यक्ति के रूप में उपयोग करना पसंद नहीं करता जब मैं बस Maxपरिणाम पर एक कुल समारोह का उपयोग करने जा रहा हूं । मैं यह भी सोचता हूं (मैंने अभी तक इसका परीक्षण नहीं किया है) कि उत्पन्न एसक्यूएल एक अतिरिक्त सबसेलेट क्वेरी का उपयोग करेगा, जबकि मेरा सिर्फ शून्य वापस करके एक खाली सेट से निपटना होगा। Upvote और प्रतिक्रिया के लिए धन्यवाद! ;)
CptRobby

@ McGuireV10 इसी तरह, अगर ShoeSizeवास्तव में संबंधित Uniformइकाई में था , तो मैं उपयोग नहीं करूंगा Workers.Where(x => x.CompanyId == 8).Select(x => x.Uniform).Max(x => x.ShoeSize), इसके बजाय मैं केवल Maxफ़ंक्शन में संपूर्ण मूल्यांकन रखूंगा Workers.Where(x => x.CompanyId == 8).Max(x => x.Uniform.ShoeSize):। मैं अपने प्रश्नों में जितना संभव हो उतने तरीकों का उपयोग करना पसंद करता हूं, जिससे ईएफ को कुशलता से निर्माण करने का निर्णय लेने में सबसे बड़ी स्वतंत्रता मिल सके। ;-)
CptRobby

1
मैं EntityFramework में काम करने के लिए इसे प्राप्त नहीं कर सका। क्या कोई किसी तरह की रोशनी दिखा सकता है? (DefaultIfEmpty तकनीक ने काम किया)।
मो सिस्को

1
विस्तार विधि का एक सामान्य संस्करण:public static TResult MaxOrDefault<TElement, TResult>(this IQueryable<TElement> items, Expression<Func<TElement, TResult>> selector, TResult defaultValue = default) where TResult : struct => items.Select(selector).Max(item => (TResult?)item) ?? defaultValue;
अपेक्षाकृत_रंजनांक

32

मैक्स () उस मामले में कुछ भी वापस नहीं करेगा।

यह InvalidOperationException बढ़ाएगा क्योंकि स्रोत में कोई तत्व नहीं है।


यह केवल तभी उठाया जाएगा InvalidOperationExceptionजब सूची में मौजूद वस्तुएं एक अशक्त
Dominus.Vobiscum


10

यदि यह SQL के लिए Linq है, तो मुझे Any()इसका उपयोग करना पसंद नहीं है क्योंकि यह SQL सर्वर के लिए कई प्रश्नों का परिणाम है।

यदि ShoeSizeएक अशक्त क्षेत्र नहीं है, तो केवल .Max(..) ?? 0इच्छा का उपयोग करने से काम नहीं चलेगा, लेकिन निम्नलिखित इच्छाएं पूरी होंगी:

int maxShoeSize = Workers.Where(x = >x.CompanyId == 8).Max(x => (int?)x.ShoeSize) ?? 0;

यह पूरी तरह उत्सर्जित एसक्यूएल परिवर्तन नहीं करता है, लेकिन इसे वापस करता है 0 अगर अनुक्रम रिक्त है क्योंकि यह परिवर्तन Max()एक वापस करने के लिए int?एक के बजाय int


4
int maxShoeSize=Workers.Where(x=>x.CompanyId==8)
    .Max(x=>(int?)x.ShoeSize).GetValueOrDefault();

(यह मानते हुए कि ShoeSizeप्रकार का है int)

अगर Workersएक DbSetया ObjectSetइकाई की रूपरेखा से अपने प्रारंभिक क्वेरी एक फेंक InvalidOperationException, लेकिन एक खाली अनुक्रम के बारे में शिकायत लेकिन शिकायत materialized कि Null मूल्य एक में परिवर्तित नहीं किया जा सकता है नहीं int


2

मैक्स फेंक देगा System.InvalidOperationException "अनुक्रम में कोई तत्व नहीं हैं"

class Program
{
    static void Main(string[] args)
    {
        List<MyClass> list = new List<MyClass>();

        list.Add(new MyClass() { Value = 2 });

        IEnumerable<MyClass> iterator = list.Where(x => x.Value == 3); // empty iterator.

        int max = iterator.Max(x => x.Value); // throws System.InvalidOperationException
    }
}

class MyClass
{
    public int Value;
}

2

NB: क्वेरी के साथ DefaultIfEmpty()काफी धीमी हो सकती है । मेरे मामले में यह एक साधारण क्वेरी थी.DefaultIfEmpty(DateTime.Now.Date)

मैं इसे प्रोफाइल करने के लिए बहुत आलसी था, लेकिन जाहिर है ईएफ ने सभी पंक्तियों को प्राप्त करने की कोशिश की और फिर ले लिया Max() मूल्य लिया।

निष्कर्ष: कभी-कभी हैंडलिंग InvalidOperationExceptionबेहतर विकल्प हो सकता है।


0

आप एक टर्नरी का उपयोग कर सकते हैं .Max() विधेय को संभालने के लिए और उसके मूल्य को निर्धारित करने लिए ;

// assumes Workers != null && Workers.Count() > 0
int maxShoeSize = Workers.Max(x => (x.CompanyId == 8) ? x.ShoeSize : 0);

Workersयदि यह एक संभावना है, तो आपको संग्रह को शून्य / खाली होने पर संभालना होगा , लेकिन यह आपके कार्यान्वयन पर निर्भर करेगा।


0

आप यह कोशिश कर सकते हैं:

int maxShoeSize = Workers.Where(x=>x.CompanyId == 8).Max(x => x.ShoeSize) ?? 0;

मुझे लगता है कि यह विफल हो जाएगा क्योंकि मैक्स एक अंतर की उम्मीद कर रहा है और यह एक अशक्त हो रहा है; इसलिए null-coalescing संचालक के प्रभाव में आने से पहले ही कोई त्रुटि आ गई है।
d219

0

आप जांच कर सकते हैं कि क्या मैक्स () करने से पहले कोई कामगार हैं।

private int FindMaxShoeSize(IList<MyClass> workers) {
   var workersInCompany = workers.Where(x => x.CompanyId == 8);
   if(!workersInCompany.Any()) { return 0; }
   return workersInCompany.Max(x => x.ShoeSize);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.