2011-03-23 16 views
7

पर मैं निम्नलिखित कोड चलाने की कोशिश कर रहा हूं लेकिन एक कास्टिंग त्रुटि प्राप्त कर रहा हूं। मैं अपने कोड को फिर से लिखने के लिए कैसे लिख सकता हूं?कास्टिंग datareader मान को एक Nullable चर

boolResult= (bool?)dataReader["BOOL_FLAG"] ?? true; 
intResult= (int?)dataReader["INT_VALUE"] ?? 0; 

धन्यवाद

+0

क्या आप जानते हैं कि डेटा रीडर ["BOOL_FLAG"] और डेटा रीडर ["INT_VALUE"] में मौजूद वास्तविक मूल्य क्या है? – Jonas

उत्तर

12

डेटा पाठक पर "IsDbNull" विधि का उपयोग करें ... उदाहरण के लिए:

bool? result = dataReader.IsDbNull(dataReader["Bool_Flag"]) ? null : (bool)dataReader["Bool_Flag"] 

संपादित

आप पूरे करने होंगे कुछ ऐसा करें: बूल? nullBoolean = शून्य;

आप

bool? result = dataReader.IsDbNull(dataReader["Bool_Flag"]) ? nullBoolean : (bool)dataReader["Bool_Flag"] 
+0

यह काम नहीं करेगा। आपको 'शून्य' को 'बूल' पर डालना होगा? –

+0

आप सही हैं, मैंने अपना जवाब अपडेट किया ... मैं भूल गया कि यह नहीं बता सकता कि नल एक स्ट्रिंग है, बूल ?, MyCustomObject या – taylonr

+2

आप बस '? (बूल?) शून्य: (बूल) डेटा रीडर ["Bool_Flag"] ' –

2
bool? boolResult = null; 
int? intResult = null; 

if (dataReader.IsDBNull(reader.GetOrdinal("BOOL_FLAG")) == false) 
{ 
    boolResult = dataReader.GetBoolean(reader.GetOrdinal("BOOL_FLAG")); 
} 
else 
{ 
    boolResult = true; 
} 

if (dataReader.IsDBNull(reader.GetOrdinal("INT_VALUE")) == false) 
{ 
    intResult= dataReader.GetInt32(reader.GetOrdinal("INT_VALUE")); 
} 
else 
{ 
    intResult = 0; 
} 
+0

'== झूठी'? 'If (! ...' –

+0

बस मेरे सम्मेलन में क्या गड़बड़ है। –

8

एक समारोह में यह कर पर विचार होगा।

यहाँ कुछ मैं अतीत में प्रयोग किया है (यदि आप यह .net 4 में एक विस्तार विधि कर सकते हैं):

public static T GetValueOrDefault<T>(SqlDataReader dataReader, System.Enum columnIndex) 
{ 
    int index = Convert.ToInt32(columnIndex); 

    return !dataReader.IsDBNull(index) ? (T)dataReader.GetValue(index) : default(T); 
} 

संपादित

एक विस्तार (नहीं परीक्षण किया है, लेकिन आप प्राप्त सूचकांक के बजाय विचार), और का उपयोग कर स्तंभ नाम:

public static T GetValueOrDefault<T>(this SqlDataReader dataReader, string columnName) 
{ 

    return !dataReader.IsDBNull(dataReader[columnName]) ? (T)dataReader.GetValue(dataReader[columnName]) : default(T); 
} 

उपयोग:

0,123,
bool? flag = dataReader.GetValueOrDefault("BOOL_COLUMN"); 
+3

मुझे दूसरी एक्सटेंशन विधि पसंद है। हालांकि, चूंकि 'IsDBNull()' केवल 'int' लेता है, आप मुझे कुछ कॉल करना होगा: 'dataReader.IsDBNull (dataReader.GetOrdinal (columnName)) ' –

1

मुझे यकीन है कि मुझे इंटरवेब के आसपास कहीं और प्रेरणा मिली है लेकिन मुझे अब मूल स्रोत नहीं मिल रहा है। वैसे भी, आप नीचे दिए गए एक उपयोगिता वर्ग जो DataReader पर एक विस्तार विधि को परिभाषित करने की अनुमति देता है, इस तरह लगता है:

public static class DataReaderExtensions 
{ 
    public static TResult Get<TResult>(this IDataReader reader, string name) 
    { 
     return reader.Get<TResult>(reader.GetOrdinal(name)); 
    } 

    public static TResult Get<TResult>(this IDataReader reader, int c) 
    { 
     return ConvertTo<TResult>.From(reader[c]); 
    } 
} 

उपयोग:

reader.Get<bool?>("columnname") 

या

reader.Get<int?>(5) 

यहाँ उपयोगिता वर्ग को सक्षम करने के है :

public static class ConvertTo<T> 
{ 
    // 'Factory method delegate', set in the static constructor 
    public static readonly Func<object, T> From; 

    static ConvertTo() 
    { 
     From = Create(typeof(T)); 
    } 

    private static Func<object, T> Create(Type type) 
    { 
     if (!type.IsValueType) { return ConvertRefType; } 
     if (type.IsNullableType()) 
     { 
      return (Func<object, T>)Delegate.CreateDelegate(typeof(Func<object, T>), typeof(ConvertTo<T>).GetMethod("ConvertNullableValueType", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(new[] { type.GetGenericArguments()[0] })); 
     } 
     return ConvertValueType; 
    } 

    // ReSharper disable UnusedMember.Local 
    // (used via reflection!) 
    private static TElem? ConvertNullableValueType<TElem>(object value) where TElem : struct 
    { 
     if (DBNull.Value == value) { return null; } 
     return (TElem)value; 
    } 
    // ReSharper restore UnusedMember.Local 


    private static T ConvertRefType(object value) 
    { 
     if (DBNull.Value != value) { return (T)value; } 
     return default(T); 
    } 

    private static T ConvertValueType(object value) 
    { 
     if (DBNull.Value == value) 
     { 
      throw new NullReferenceException("Value is DbNull"); 
     } 
     return (T)value; 
    } 
} 

संपादित करें:

public static bool IsNullableType(this Type type) 
    { 
     return 
      (type.IsGenericType && !type.IsGenericTypeDefinition) && 
      (typeof (Nullable<>) == type.GetGenericTypeDefinition()); 
    } 
+0

शानदार। धन्यवाद। –

0

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

-2

this संस्करण आज़माएं। यह कुछ बुनियादी रूपांतरण करता है और डिफ़ॉल्ट मान भी प्रबंधित करता है।

+1

जबकि यह सैद्धांतिक रूप से प्रश्न का उत्तर दे सकता है, [यह बेहतर होगा] (http: //meta.stackexcha nge.com/q/8259) यहां उत्तर के आवश्यक हिस्सों को शामिल करने के लिए, और संदर्भ के लिए लिंक प्रदान करें। –

2

यहाँ एक जवाब है कि उपयोगी हो सकता है नहीं है: https://stackoverflow.com/a/3308515/1255900

आप "के रूप में" कीवर्ड का उपयोग कर सकते हैं।टिप्पणियों में उल्लिखित सावधानी बरतें।

nullableBoolResult = dataReader["BOOL_FLAG"] as bool?; 

या, यदि आप nullables उपयोग नहीं कर रहे हैं, अपने मूल पोस्ट में के रूप में:

boolResult = (dataReader["BOOL_FLAG"] as bool?) ?? 0; 
+0

मैंने डेटा रीडर ["long_col"] लंबे समय तक कोशिश की? एक लंबे समय तक, लेकिन यह सभी मामलों में मूल्य को शून्य करने के लिए निर्धारित करता है। – bpeikes

1

यहाँ एक विस्तार विधि पर मेरे शॉट है। कॉलम नाम सेमेन्टिक्स और default(T) पर वापस आ जाता है जब एक शून्य का सामना करना पड़ता है।

public static class DbExtensions 
{ 
    public static T ReadAs<T>(this IDataReader reader, string col) 
    { 
     object val = reader[col]; 
     if (val is DBNull) 
     { 
      // Use the default if the column is null 
      return default(T); 
     } 
     return (T)val; 
    } 
} 

यहां नमूना उपयोग है। याद रखें कि string संदर्भ प्रकार होने के बावजूद, यह DBNull से null पर डालने में असफल रहेगा। int? के साथ भी यही सच है।

public Facility Bind(IDataReader reader) 
{ 
    var x = new Facility(); 
    x.ID = reader.ReadAs<Guid>("ID"); 
    x.Name = reader.ReadAs<string>("Name"); 
    x.Capacity = reader.ReadAs<int?>("Capacity"); 
    x.Description = reader.ReadAs<string>("Description"); 
    x.Address = reader.ReadAs<string>("Address"); 
    return x; 
} 
संबंधित मुद्दे