2012-06-01 13 views
15

मेरे पास पैरामीटर सेट करने के लिए निम्न कोड है जो SQL सर्वर डेटाबेस में VARCHAR कॉलम सेट करने के लिए INSERT कथन में उपयोग किया जाएगा। मेरी वैल्यू ऑब्जेक्ट (नाम इलो) में एक ऐसी प्रॉपर्टी है जिसे स्ट्रिंग.इक्टी के लिए प्रारंभ किया जाता है, और उसके बाद एक्सएमएल से कुछ मूल्यों पर सेट हो जाता है, या यदि एक्सएमएल तत्व खाली है तो यह सिर्फ स्ट्रिंग के रूप में रहता है। लक्षण।डीबीएनयूएल को पैरामीटर सेट करना। टर्नरी सिंटैक्स का उपयोग करके वैल्यू त्रुटि देता है?

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

database.AddInParameter(cmd, "@description", DbType.String, 
          (ilo.Description.Equals(string.Empty)) ? 
          DBNull.Value : 
          ilo.Description); 

तो बुनियादी तौर पर मैं कह रहा हूँ, अगर ilo.Description string.empty बराबर होती है, DBNull.Value लिए पैरामीटर सेट, अन्यथा ilo.Description पर सेट करें।

यह दृश्य स्टूडियो में निम्न त्रुटि देता है ...

त्रुटि 141 सशर्त अभिव्यक्ति का प्रकार निर्धारित नहीं किया जा सकता है, क्योंकि 'System.DBNull' और 'स्ट्रिंग'

क्यों बीच कोई अंतर्निहित रूपांतरण है वहाँ?

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

if(ilo.Description.Equals(string.Empty)) 
{ 
    database.AddInParameter(cmd, "@description", DbType.String, DBNull.Value); 
} 
else 
{ 
    database.AddInParameter(cmd, "@description", DbType.String, ilo.Description); 
} 

मैंने अन्य पोस्ट की खोज की, और नीचे दिया गया, लेकिन यह वास्तव में मेरे प्रश्न का उत्तर नहीं देता है।

EntLib Way to Bind "Null" Value to Parameter

मैं, क्यों में अधिक रुचि रखते कर रहा हूँ क्योंकि यह एक स्पष्ट समाधान का सिर्फ इनलाइन (त्रिगुट) वाक्य रचना के बजाय एक अगर/बाकी कथन का उपयोग करने के लिए है?

इस लिंक पर एक तरह का जवाब है, लेकिन मुझे एक बेहतर स्पष्टीकरण चाहिए क्योंकि ऐसा लगता है कि यह बीएस नहीं है कि यह काम नहीं करता है; मैं इसे एक बग कहूंगा!

http://msdn.microsoft.com/en-us/library/ty67wk28.aspx

+1

आप टर्नरी ऑपरेटर और इस तरह की समस्या [इस जवाब में] पर जानकारी प्राप्त कर सकते हैं [http://stackoverflow.com/questions/4290203/simple-c-why-assigning-null-in-ternary-operator-fails -नो-निहित-रूपांतरण) – Steve

+0

धन्यवाद स्टीव। आपका लिंक वह था जो मैं वास्तव में खोज रहा था। मुझे लगता है कि यह .NET का बेवकूफ पहलू है; वे सिर्फ मूल्यांकन क्यों नहीं करते हैं कि प्रत्येक संभावित परिणाम के प्रकार कथन के अनुरूप हैं या नहीं। यानी यदि आप ऑब्जेक्ट ओ = (कुछबूल) कहते हैं? कुछ INT32: कुछ स्ट्रिंग; आपको एक त्रुटि मिलती है, लेकिन यह मूल्यांकन करना कितना आसान होगा कि दोनों परिणामों को किसी ऑब्जेक्ट पर निहित किया जा सकता है, यह मूल्यांकन करने के बजाय कि कुछ स्ट्रिंग को कुछ Int32 पर डाला जा सकता है या नहीं? यह मेरे लिए बेवकूफ लगता है, लेकिन मुझे लगता है कि यह कैसा है। धन्यवाद! – Jim

+0

मैं यह भी टिप्पणी करना चाहूंगा कि मैं इस धागे के उत्तरों की गति और सटीकता से बहुत प्रभावित हूं। यह समुदाय कमाल है! सबको धन्यवाद! – Jim

उत्तर

34

यह एक सामान्य त्रुटि जब सशर्त ऑपरेटर का उपयोग लोग प्राप्त करते हैं। इसे ठीक करने के लिए, केवल एक या दोनों परिणामों को एक सामान्य आधार प्रकार पर डालें।

ilo.Description.Equals(string.Empty) 
    ? (object)DBNull.Value 
    : ilo.Description 

समस्या आपके द्वारा देखी गई त्रुटि संदेश में प्रकट हुई है।

सशर्त अभिव्यक्ति का प्रकार निर्धारित नहीं किया जा सकता है, क्योंकि 'System.DBNull' और 'स्ट्रिंग'

के बीच कोई अंतर्निहित रूपांतरण एक स्ट्रिंग एक DBNull नहीं है वहाँ है, और एक DBNull एक स्ट्रिंग नहीं है। इसलिए, संकलक अभिव्यक्ति के प्रकार को निर्धारित नहीं कर सकता है। एक सामान्य आधार प्रकार (object) में एक कास्ट का उपयोग करके, आप एक परिदृश्य बनाते हैं जहां संकलक यह निर्धारित कर सकता है कि स्ट्रिंग ऑब्जेक्ट में भी परिवर्तनीय है, इसलिए अभिव्यक्ति का प्रकार ऑब्जेक्ट के रूप में निर्धारित किया जा सकता है, जो अच्छी तरह से कोड की आपकी लाइन के साथ फिट बैठता है जो डीबी पैरामीटर तर्क के रूप में भी अपेक्षा करता है।

+0

स्टीव की टिप्पणी अधिक जानकारी के साथ एक लिंक देती है, लेकिन आपका जवाब भी बहुत सही है। ऐसा करने के लिए मुझे बस गूंगा लगता है। मुझे जावा में विश्वास है कि ऐसा नहीं होता है। – Jim

1

आपको संकलन त्रुटि मिलती है क्योंकि टर्नरी अभिव्यक्ति के दोनों भाग एक ही प्रकार के होने चाहिए।इस विशेष स्थिति के लिए सबसे आसान तरीके को एक वस्तु के लिए दोनों कास्ट करने के लिए है:

database.AddInParameter(cmd, "@description", DbType.String, 
          (ilo.Description.Equals(string.Empty)) ? 
          (object) DBNull.Value : 
          (object) ilo.Description); 
+0

जैसा कि आलसीबेरेज़ोवस्की ने सुझाव दिया है, डीबीएनयूएल की बजाय शून्य का उपयोग करना भी बेहतर है। यहां पर चलें। मुझे लगता है कि आपको केवल डीबीएनयूएल का उपयोग करने की आवश्यकता है। एक डेटाटेडर या डेटासेट से पढ़ते समय वैल्यू। – Tuan

2

एंथोनी वास्तव में सही है तो वह सही जवाब मिलना चाहिए, फिर भी यहां एक विस्तार विधि है क्योंकि मैं ऊब हूँ ...

अपने परिदृश्य में
public static object NullCheck(this string self) 
    { 
     return (string.IsNullOrEmpty(self)) ? (object)DBNull.Value : self; 
    } 

उपयोग:

database.AddInParameter(cmd, "@description", DbType.String, 
          ilo.Description.NullCheck()); 
+0

अच्छी चीजें। भले ही मैं शायद इस विधि का उपयोग नहीं करूंगा, फिर भी उसने मुझे सी # के बारे में कुछ बातें सिखाईं जो मुझे पहले नहीं पता था; जैसे मैंने पहले स्ट्रिंग पर IsNullOrEmpty विधि भी नहीं देखी थी। मैं जावा के लिए बहुत प्रयोग किया जाता हूं, और अधिक सी # सीखने में मुझे खुशी है। धन्यवाद! – Jim

+0

कोई चिंता नहीं, इसके बारे में सोचने के बाद, पैरामीटर कोलेक्शन/डेटाबेस ऑब्जेक्ट पर विस्तार विधि को एक रैपर प्रदान करने के लिए बेहतर हो सकता है जो आपके इच्छित तरीके से नल को संभालता है। – Marlon

4

यह है कि मैं क्या एक और धागा में पाया और यह मेरे लिए महान काम किया है:

yourVariable ?? (object)DBNull.Value 

मुझे उम्मीद है कि यह मदद करता है।

संबंधित मुद्दे