Primero, déjenme explicarles la situación actual: estoy leyendo registros de una base de datos y los coloco en un objeto para su uso posterior; hoy surgió una pregunta sobre el tipo de base de datos para la conversión de tipo C# (¿casting?).Cómo (eficientemente) convertir (¿emitir?) Un campo SqlDataReader a su correspondiente tipo de C#?
Veamos un ejemplo:
namespace Test
{
using System;
using System.Data;
using System.Data.SqlClient;
public enum MyEnum
{
FirstValue = 1,
SecondValue = 2
}
public class MyObject
{
private String field_a;
private Byte field_b;
private MyEnum field_c;
public MyObject(Int32 object_id)
{
using (SqlConnection connection = new SqlConnection("connection_string"))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "sql_query";
using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SingleRow))
{
reader.Read();
this.field_a = reader["field_a"];
this.field_b = reader["field_b"];
this.field_c = reader["field_c"];
}
}
}
}
}
}
Ésta es (obviamente) no porque los tres this.field_x = reader["field_x"];
llamadas están lanzando el error Cannot implicitly convert type 'object' to 'xxx'. An explicit conversion exists (are you missing a cast?).
compilador.
Para corregir esto Actualmente conocimientos de dos maneras (Vamos a usar el ejemplo field_b
): es el número uno y el número dos this.field_b = (Byte) reader["field_b"];
es this.field_b = Convert.ToByte(reader["field_b"]);
.
El problema con la opción número uno es que DBNull
campos están lanzando excepciones como el elenco está fallando (incluso con tipos anulables como String
), la hormiga el problema número dos es que no es la preservación de los valores nulos (el Convert.ToString(DBNull)
produce una String.Empty
), y no puedo usarlos con enumeraciones también.
Así, después de un par de búsquedas en Internet y aquí en stackoverflow, lo que se me ocurrió es:
public static class Utilities
{
public static T FromDatabase<T>(Object value) where T: IConvertible
{
if (typeof(T).IsEnum == false)
{
if (value == null || Convert.IsDBNull(value) == true)
{
return default(T);
}
else
{
return (T) Convert.ChangeType(value, typeof(T));
}
}
else
{
if (Enum.IsDefined(typeof(T), value) == false)
{
throw new ArgumentOutOfRangeException();
}
return (T) Enum.ToObject(typeof(T), value);
}
}
}
De esta manera me debería manejar cada caso.
Pregunta es: ¿Emite algo más? ¿Estoy haciendo un WOMBAT (Waste of Money, Brain And Time) ya que hay una forma más rápida y limpia de hacerlo? Está todo correcto? ¿Lucro?
Esto se ve muy amplio y genérico para mí. La clase SqlDataReader tiene algunas funciones de tipo .GetInt32(), .GetBytes() para la conversión que harán algo de esto por usted, pero creo que todavía necesita verificar nulos. También buscaría en LINQ o en un ORM, ellos se encargarían de detalles como este para usted. –
Mire los diversos métodos GetXXX del lector de datos. Tal vez son lo que estás buscando. –
¿Has intentado utilizar *** FromDatabase ***? final simple al respecto usando *** int, int ?, string, DateTime ?, Enum *** values? – Kiquenet