'Int32' को टाइप करने के लिए कास्ट विफल रही क्योंकि भौतिक मूल्य शून्य है


192

मेरे पास निम्न कोड है। मुझे त्रुटि मिल रही है:

"टाइप टू वैल्यू टाइप 'इंट 32' विफल हो गया क्योंकि भौतिक मूल्य शून्य है। या तो परिणाम प्रकार का जेनेरिक पैरामीटर या क्वेरी को अशक्त प्रकार का उपयोग करना चाहिए।"

जब CreditHistory टेबल का कोई रिकॉर्ड नहीं है।

var creditsSum = (from u in context.User
                  join ch in context.CreditHistory on u.ID equals ch.UserID                                        
                  where u.ID == userID
                  select ch.Amount).Sum();

मैं शून्य मानों को स्वीकार करने के लिए क्वेरी को कैसे संशोधित कर सकता हूं?

जवाबों:


328

एक linq-to-sql क्वेरी कोड के रूप में निष्पादित नहीं की जाती है, बल्कि SQL में अनुवादित होती है। कभी-कभी यह एक "टपका हुआ अमूर्त" होता है जो अप्रत्याशित व्यवहार करता है।

ऐसा ही एक मामला अशक्त हैंडलिंग है, जहां विभिन्न स्थानों पर अप्रत्याशित नल हो सकते हैं। ...DefaultIfEmpty(0).Sum(0)इस (काफी सरल) मामले में मदद कर सकता है, जहां कोई तत्व और एसक्यूएल का SUMरिटर्न नहीं हो सकता है nullजबकि c # उम्मीद 0।

एक अधिक सामान्य दृष्टिकोण का उपयोग करना है ??जो कि COALESCEजब भी कोई जोखिम होता है तो अनुवाद किया जाएगा कि उत्पन्न SQL एक अप्रत्याशित नल देता है:

var creditsSum = (from u in context.User
              join ch in context.CreditHistory on u.ID equals ch.UserID                                        
              where u.ID == userID
              select (int?)ch.Amount).Sum() ?? 0;

यह पहली बार int?C # संकलक को बताता है कि यह अभिव्यक्ति वास्तव में वापस आ सकती है null, भले ही Sum()रिटर्न ए int। फिर हम मामले ??को संभालने के लिए सामान्य ऑपरेटर का उपयोग करते हैं null

इस उत्तर के आधार पर, मैंने LINQ से SQL और LINQ दोनों एंटिटीज के विवरण के साथ एक ब्लॉग पोस्ट लिखी ।


3
धन्यवाद एंडर्स, DefaultIfEmpty (0) .Sum () के साथ समाधान मेरे लिए ठीक काम करता है। मैं भी (int?) के साथ दूसरे समाधान की कोशिश की है ... ?? 0 ..., लेकिन यह पहले की तरह ही अपवाद फेंकता है ..
जोसिम

अंत में यह परीक्षण करने के लिए चारों ओर हो गया और इसे समायोजित किया, इसलिए अब दूसरा संस्करण भी काम करता है।
एंडर्स एबेल

1
खाली डेटासेट पर लागू होने पर सम () और अन्य कुल कार्य शून्य हो जाएंगे। उनकी परिभाषा के विपरीत, वास्तव में वे अंतर्निहित प्रकार का एक अशक्त संस्करण लौटाते हैं।
सनकैट

2
@recursive: आपका उदाहरण LINQ-to-Objects है, न कि LINQ-to-SQL (या LINQ-to-Entry)। उनके अंतर्निहित डेटा प्रदाता उन्हें अलग तरह से व्यवहार करते हैं।
सनकैट २२

यह एक अच्छा विचार था। मैंने अपनी वापसी वस्तु को अशक्त गुणों के लिए अद्यतन किया और यह एक आकर्षण के रूप में काम किया।
क्रेमेना लालोवा

8

एक Amountअशक्त क्षेत्र की अनुमति देने के लिए , केवल नल को 0 में परिवर्तित करने के लिए अशक्त सहवर्ती ऑपरेटर का उपयोग करें।

var creditsSum = (from u in context.User
              join ch in context.CreditHistory on u.ID equals ch.UserID                                        
              where u.ID == userID
              select ch.Amount ?? 0).Sum();

1
जब मैं आपके टिप का उपयोग करता हूं, तो कंपाइलर कहता है: ऑपरेटर '??' 'int' और 'int' प्रकार के ऑपरेंड पर लागू नहीं किया जा सकता। क्या मैं कुछ भूल गया हूँ?
जोसिम

@ ज़ोसिम: यह int?पहली बार कलाकारों को जोड़ने का कारण है ।
एंडर्स हाबिल

मैं int जोड़ा है ?, लेकिन एक ही अपवाद। मैं आपका आभारी रहूंगा, जब आपके पास देव एनवी होगा। इस सिंटैक्स में क्या गलत है, इसकी जाँच करने के लिए।
जोसिम

1
@ ज़ोसिम: मुझे समस्या समझ में नहीं आती। यदि Amountकोई है int, तो हम पहले से ही सुनिश्चित हैं कि यह अशक्त नहीं हो सकता है, और तालमेल अनावश्यक है। यदि आपको वह त्रुटि मिल रही है, जो आपने कहा है, तो Amountयह अशक्त नहीं है, यह सिर्फ एक है int, इस मामले में शायद आपको अशक्त होने की अनुमति देने के लिए डिज़ाइनर में अपना linq2sql dbml कॉलम बदलना होगा।
पुनरावर्ती

1
@ संक्षिप्त: राशि अंतर है, यह ठीक है। राशि का पहले से ही मूल्य है। मुझे लगता है, कि उपरोक्त त्रुटि है क्योंकि CreditHistory तालिका खाली है। मेरे पास उपयोगकर्ता तालिका में एक रिकॉर्ड है और CreditHistory तालिका में 0 रिकॉर्ड है और त्रुटि की पुष्टि की जाती है। जब मैं DefaultIfEmpty (0) .Sum () का उपयोग करता हूं तो यह ठीक काम करता है, लेकिन इसके साथ ?? 0 यह त्रुटि फेंकता है। मेरा एक और सवाल यह है कि इस मामले में सबसे अच्छा अभ्यास क्या है? DefaultIfEmpty (0)? धन्यवाद
ज़ॉसीम

4

आप aggregateफ़ंक्शन का उपयोग कर रहे हैं, जिसमें कार्रवाई करने के लिए आइटम नहीं मिल रहे हैं, आपको सत्यापित करना चाहिए कि linq क्वेरी नीचे के रूप में कुछ परिणाम दे रही है:

var maxOrderLevel =sdv.Any()? sdv.Max(s => s.nOrderLevel):0

11
यह sdv को दो बार निष्पादित करेगा। जो आप IQueryables के लिए नहीं चाहते हैं
Ody

4

यह त्रुटि संदेश तब था जब मैं एक दृश्य से चयन करने का प्रयास कर रहा था।

समस्या यह थी कि हाल ही में कुछ नई नल पंक्तियाँ प्राप्त हुईं (सबस्क्राइबर्ड कॉलम में), और इसे EDMX (EF डेटाबेस पहले) में अपडेट नहीं किया गया था।

स्तंभ को काम करने के लिए अशक्त प्रकार होना चाहिए।

var Dealer = Context.Dealers.Where (x => x.dealerCode == DealerCode) .FirstOrDefault ();

ताज़ा करने से पहले देखें:

public int SubscriberId { get; set; }

ताज़ा देखने के बाद:

public Nullable<int> SubscriberId { get; set; }

ईडीएमएक्स में वापस देखने और जोड़ने का काम किया।

आशा है कि यह किसी की मदद करता है।


यह मेरा मुद्दा और मेरा जवाब भी था
सिमोन निकोल्स

4

मैंने इस कोड का उपयोग किया है और यह सही तरीके से प्रतिक्रिया करता है, केवल आउटपुट वैल्यू अशक्त है।

var packesCount = await botContext.Sales.Where(s => s.CustomerId == cust.CustomerId && s.Validated)
                                .SumAsync(s => (int?)s.PackesCount);
                            if(packesCount != null)
                            {
                                // your code
                            }
                            else
                            {
                                // your code
                            }

1

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

var credits = from u in context.User
              join ch in context.CreditHistory 
                  on u.ID equals ch.UserID                                        
              where u.ID == userID
              select ch;

var creditSum= credits.Sum(x => (int?)x.Amount) ?? 0;

0

रनटाइम में इस कोड के साथ Entity Framework 6 में यह त्रुटि मिली:

var fileEventsSum = db.ImportInformations.Sum(x => x.FileEvents)

LeandroSoares से अपडेट:

एकल निष्पादन के लिए इसका उपयोग करें:

var fileEventsSum = db.ImportInformations.Sum(x => (int?)x.FileEvents) ?? 0

मूल:

इसे बदला गया और फिर इसने काम किया:

var fileEventsSum = db.ImportInformations.Any() ? db.ImportInformations.Sum(x => x.FileEvents) : 0;

1
यह दो बार निष्पादित नहीं करेगा?
नवफाल

यह एक अच्छा जवाब नहीं है। यह दो बार DB से प्राप्त होगा।
लिएंड्रो सोरेस

@nawfal यह सच है लेकिन यह रनटाइम त्रुटि से काफी बेहतर है। आप linq-to-sql का उपयोग पूरी तरह से कर सकते हैं लेकिन लैम्ब्डा के साथ यह कठिन है। आप निश्चित रूप से अपवाद को पकड़ सकते हैं, लेकिन मुझे लगता है कि समाधान दो निष्पादन से भी बदतर है।
ओग्लास

@LeandroSoares उपरोक्त टिप्पणी देखें
ओग्लास

1
@LeandroSoares एक अच्छा लगा! मैंने अपना उत्तर अपडेट किया और आपके द्वारा प्रदान किए गए कोड का उपयोग किया और इसके बजाय इसका उपयोग करने का वर्णन किया।
ओग्लास

0

मैं भी उसी समस्या का सामना कर रहा था और स्तम्भ बनाने के माध्यम से हल कर रहा था ""? ऑपरेटर।

Sequnce = db.mstquestionbanks.Where(x => x.IsDeleted == false && x.OrignalFormID == OriginalFormIDint).Select(x=><b>(int?)x.Sequence</b>).Max().ToString();

कभी-कभी अशक्त लौट आता है।

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