Un método genérico tiene la ventaja de que puede reducir una gran cantidad de código inflado, pero de lo contrario producir su propio contenedor para cada tipo de datos le brinda la flexibilidad de tener un manejo personalizado. Y muy probablemente sus consultas db tendrán un efecto notable en el rendimiento que el modo de recuperación.
Le sugiero que escriba un conjunto de sus propios métodos de extensión que tener un enfoque genérico. La extensión del método en IDataReader
le da la ventaja de no propagar los métodos en sub tipos de objetos completos. He tenido que manejar los tipos individualmente ya que varios conectores se comportaron de manera diferente, especialmente con el tipo Guid
. También es difícil saber si el lector de datos lee el valor 0
o DBNull
cuando devuelve 0
para ambos casos. Digamos que hay un campo de enumeración en su tabla con un valor nulo. ¿Por qué querrías que se leyera como la primera enumeración?
Sólo tiene que llamar:
dataReader.GetInt("columnName1")
dataReader.GetString("columnName3")
dataReader.GetFloat("columnName3")
Y los métodos:
public static int? GetInt(this IDataReader r, string columnName)
{
var i = r[columnName];
if (i.IsNull())
return null; //or your preferred value
return (int)i;
}
public static bool IsNull<T>(this T obj) where T : class
{
return (object)obj == null || obj == DBNull.Value;
}
Y del mismo modo,
public static string GetString(this IDataReader r, string columnName)
{
}
public static float GetFloat(this IDataReader r, string columnName)
{
}
Si realmente desea una función genérica que puede tener también.
public static T Get<T>(this IDataReader r, string columnName, T defaultValue = default(T))
{
var obj = r[columnName];
if (obj.IsNull())
return defaultValue;
return (T)obj;
}
Así lo llaman
dataReader.Get<int>(1); //if DBNull should be treated as 0
dataReader.Get<int?>(1); //if DBNull should be treated as null
dataReader.Get<int>(1, -1); //if DBNull should be treated as a custom value, say -1
Dicho esto, el error se debe a que usted no está lanzando con el tipo correcto como se ha señalado en los comentarios. Podría haber ido con controles incorporados en DBNull
, pero no para evitar que los datos se lean varias veces desde el lector, inspired from this curious case of microoptimization
Qué tipo de datos es columnName3 en la base de datos? – RQDQ
¿has visto Linq to Dataset? –
@RQDQ, es el tipo de datos SQL Server 'real'. Intenté replicar en la aplicación de la consola con el siguiente código: object objValue = 7200000; float floatValue = (float) objValue; // falla aquí – iniki