2009-02-26 12 views
6

Estoy leyendo un resultado de una base de datos MS SQL 2008 con un tipo de columna de dbtype.time desde un lector de datos, usando C# con el marco DAAB 4.0.Cómo convertir el Datareader Resultado de DbType.Time al objeto Timespan?

Mi problema es que los documentos de MSDN dicen que dbtype.time debe asignarse a un intervalo de tiempo, pero el único constructor cercano para el intervalo de tiempo que veo acepta un largo, y el resultado devuelto por el lector de datos no se puede convertir a largo, ni directamente a un espacio de tiempo.

yo encontramos este Article whichs muestra datareader.getTimeSpan método(), pero no parece que la datareader en daab 4.0 para tener este método.

Entonces, ¿cómo convierto el resultado del lector de datos a un objeto de intervalo de tiempo?

Respuesta

6

GetTimeSpan es un método de OleDbDataReader y SqlDataReader (pero no de la interfaz IDataReader más genérico que ExecuteReader rendimientos de daab). Supongo que la instancia IDataReader que DAAB le ha devuelto es en realidad una instancia de SqlDataReader. Esto le permite acceder al método GetTimeSpan echando la instancia IDataReader appropiately:

using (IDataReader dr = db.ExecuteReader(command)) 
{ 
    /* ... your code ... */ 
    if (dr is SqlDataReader) 
    { 
     TimeSpan myTimeSpan = ((SqlDataReader)dr).GetTimeSpan(columnIndex) 
    } 
    else 
    { 
     throw new Exception("The DataReader is not a SqlDataReader") 
    } 
    /* ... your code ... */ 
} 

Editar: Si la instancia IDataReader no es un SqlDataReader entonces usted puede ser que falte el atributo provider de la cadena de conexión definida en su app.config (o web.config).

0

¿Cuál es el tipo .NET del valor de la columna? Si es un DateTime, puede pasar el valor de su propiedad Ticks (largo) al constructor TimeSpan. P.ej.

var span = new TimeSpan(colValue.Ticks); 
9

Ha intentado un reparto directo de esta manera?

TimeSpan span = (TimeSpan)reader["timeField"]; 

Acabo de probar esto de manera rápida en mi máquina y funciona bien cuando se "TimeField" es un tipo de datos de tiempo en la base de datos (SQL).

+0

Tanto la suya como la de Ken son buenas. Sin embargo, si el valor es nulo, el mensaje de excepción de la solución de Ken es más descriptivo. 'SqlNullValueException - Los datos son nulos. Este método o propiedad no puede invocarse en valores nulos' VS 'InvalidCastException - El molde especificado no es válido'. – TheWanderingMind

+1

Para responder al comentario de BishopBarber si la columna puede ser anulada, conviene convertirla a TimeSpan. tipo anulable y comprobar null. 'TimeSpan? span = reader ["tsfield"] == DBNull.Value? (TimeSpan?) Null: (TimeSpan?) Reader ["tsfield"] ' –

+0

Encontré esta solución mejor porque a menudo no accedo a mi lector de datos por índice. Sin embargo, tengo un método intermedio que comprueba nulo. – MichaelChan

1

Esta es mi opinión:


using (IDataReader reader = db.ExecuteReader(command)) 
{ 
    var timeSpan = reader.GetDateTime(index).TimeOfDay; 
} 

limpiador, tal vez!

+0

La capa de la base de datos arroja una 'InvalidCastException' cuando devuelve un tipo' TIME ', pero trato de leer con 'GetDateTime()'. – binki

Cuestiones relacionadas