2010-04-09 11 views
10

(LocalVariable) ABC.string (Name) = (Idatareader) datareader.GetString (0);Modo nulo para obtener valores de un IDataReader

este valor del nombre proviene de la base de datos ... ¿Qué ocurre aquí si el valor de este nombre es nulo mientras se lee arrojando una excepción?

Estoy haciendo manualmente algunas condiciones aquí. No quiero escribir una regulación manual para comprobar todas las variables de mis ..

que estoy haciendo algo como esto ahora ..

string abc = (Idatareader)datareader.GetValue(0); 
if(abc = null) 
    //assiging null 
else 
    assiging abc value 

es que hay algo así como podemos escribir método de extensión para esto? gracias

Respuesta

20

que aquí hay una pareja métodos de extensión que va muy bien concluir todas sus preocupaciones en torno a la recuperación de los valores inflexible de tipos desde un lector de datos. Si el valor es DbNull, se devolverá el valor predeterminado del tipo. En el caso de string que es una clase, se devolverá un null. Si el campo era int, se devolvería 0. Además, si está esperando un int?, digamos desde un campo nullable int, se devolverá null.

uso específico para el caso de Kumar:

string abc = datareader.GetValueOrDefault<string>(0); 

Uso general

var name = GetValueOrDefault<string>(reader, "Name"); 

o

var name = reader.GetValueOrDefault<string>("Name"); 

o

var name = reader.GetValueOrDefault<string>(0); 

Extensión

public static class NullSafeGetter 
{ 
    public static T GetValueOrDefault<T>(this IDataRecord row, string fieldName) 
    { 
     int ordinal = row.GetOrdinal(fieldName); 
     return row.GetValueOrDefault<T>(ordinal); 
    } 

    public static T GetValueOrDefault<T>(this IDataRecord row, int ordinal) 
    { 
     return (T)(row.IsDBNull(ordinal) ? default(T) : row.GetValue(ordinal)); 
    } 
} 

de http://skysanders.net/subtext/archive/2010/03/02/generic-nullsafe-idatarecord-field-getter.aspx

+0

En caso de que el valor sea DBNull y esperamos int, ¿no es malo devolver 0? ¿No deberíamos lanzar una excepción en ese caso, ya que algo obviamente está mal? ¿Deberíamos esperar int? o pregunta produce el tipo incorrecto del valor? Poner 0 donde no hay un valor real podría estar bien en algunos casos particulares, pero tener esto en una biblioteca común podría dar lugar a errores muy sutiles, creo. – poke

+0

Es conveniente poder pasar un valor predeterminado como parámetro: 'public static T GetValueOrDefault (esta fila IDataRecord, int ordinal, T defaultValue = default (T))' – mistika

+0

@poke para el caso de int desea que se tenga T 'int?' por lo que el valor de retorno podría ser nulo. –

0

que haría uso de algo como esto:

string abc = (IDataReader)datareader.GetValue(0) ?? "Default"; 
+0

¿Qué es lo que va a hacer? ¿me puede explicar gracias? – kumar

+0

"El operador ?? se llama el operador nulo-coalescente y se usa para definir un valor predeterminado para un tipo de valor que se puede anular así como tipos de referencia. Devuelve el operando de la izquierda si no es nulo; de lo contrario, devuelve el operando correcto ". http://msdn.microsoft.com/en-us/library/ms173224.aspx – Powerlord

+2

ha probado esto porque 'DbNull! = null' –

2

Mi solución es que:

private static T GetValue<T>(object o) { 
    if (typeof(DBNull) != o.GetType()) { 
     return (T) o; 
    } 
    return default(T); 
} 

Cuando, Status = GetValue<string>(currentDataRow["status"])

+4

En lugar de usar typeof() y GetType() no puede hacer esto: "if (o es DBNull)". En mi opinión, es más legible. – JMS10

+2

¿Qué pasa con 'if (o == DBNull.Value)'? –

+0

Las posibilidades son 'o == DBNull.Value' es más rápido que' o es DBNull', y ciertamente que 'typeof (DBNull)! = O.GetType()'. – nawfal

3

similares a @ cielo-Sanders respuesta, pero menos estricto con las conversiones:

public static T Get<T>(this IDataRecord row, string fieldName) 
{ 
    int ordinal = row.GetOrdinal(fieldName); 
    return row.Get<T>(ordinal); 
} 

public static T Get<T>(this IDataRecord row, int ordinal) 
{ 
    var value = row.IsDBNull(ordinal) ? default(T) : row.GetValue(ordinal); 
    return (T)Convert.ChangeType(value, typeof(T)); 
} 
1

Combinando mejores soluciones y sugerencias, he aquí una C# 6 expresión de flecha versión con soporte para GetValue<T> y GetValueOrDefault<T> con parámetros de valor predeterminados opcionales.

public static class DataRecordExtensions { 
    /// <summary> 
    /// Generically extracts a field value by name from any IDataRecord as specified type. Will throw if DNE. 
    /// </summary> 
    public static T GetValue<T>(this IDataRecord row, string fieldName) 
     => row.GetValue<T>(row.GetOrdinal(fieldName)); 

    /// <summary> 
    /// Generically extracts a field value by ordinal from any IDataRecord as specified type. Will throw if DNE. 
    /// </summary> 
    public static T GetValue<T>(this IDataRecord row, int ordinal) 
     => (T)row.GetValue(ordinal); 

    /// <summary> 
    /// Generically extracts a field value by name from any IDataRecord as specified type. Will return default generic types value if DNE. 
    /// </summary> 
    public static T GetValueOrDefault<T>(this IDataRecord row, string fieldName, T defaultValue = default(T)) 
     => row.GetValueOrDefault<T>(row.GetOrdinal(fieldName), defaultValue); 

    /// <summary> 
    /// Generically extracts a field value by ordinal from any IDataRecord as specified type. Will return default generic types value if DNE. 
    /// </summary> 
    public static T GetValueOrDefault<T>(this IDataRecord row, int ordinal, T defaultValue = default(T)) 
     => (T)(row.IsDBNull(ordinal) ? defaultValue : row.GetValue(ordinal)); 
} 
Cuestiones relacionadas