2011-10-18 11 views
7

En el siguiente código, la instrucción 1 arroja una excepción de conversión. Me pregunto por qué no es unboxing?
La declaración 2 funciona bien, pero quiero saber por qué la primera es incorrecta.Casting Excepción al intentar obtener valor de ExecuteScalar()

using (IDbCommand command = connection.CreateCommand()) 
{ 
    command.CommandText = string.Format("SELECT COUNT(1) FROM {0}", tableName); 
    int count = (int)command.ExecuteScalar(); //statement 1 
} 
//int count = Convert.ToInt32(command.ExecuteScalar()); //statement 2 
+0

si usa Int32 count = (Int32) cmd.ExecuteScalar(); aún recibes excepciones? – Zenwalker

+2

@zenwalker: 'int' y' Int32' son sinónimos. – Heinzi

+2

¿Cuál es el mensaje de excepción exacto que obtienes? – Heinzi

Respuesta

0

Solo se puede convertir a int si el campo de la base de datos es de hecho un entero de 32 bits con signo. Si es largo y/o sin signo, el lanzamiento fallará.

Dado que es poco probable que el tipo cambie, puede dividir la ejecución y el molde, y establecer un punto de corte justo antes del molde para ver el tipo correcto.

0

Fundición y conversión no son lo mismo. Casting a un int le está diciendo al compilador que los datos devueltos por ExecuteScalar ya son un int y deben colocarse en una variable int.

Con la conversión intentará tomar los datos devueltos por ExecuteScalar (independientemente del tipo de datos) e intentará convertirlos a un int.

Un ejemplo común es si su consulta devuelve una cadena "42". No puede convertir "42" en int porque es una cadena, pero puede convertirla.

+0

Muy poco probable que se devuelva "COUNT (1)" como una cadena. –

0

Me explico sobre Dylan Smith y Darcara. Tiene que ver con el boxeo y el desempaquetado. Cambiar el código para esto:

using (System.Data.IDbCommand command = connection.CreateCommand()) 
{ 
    command.CommandText = string.Format("SELECT COUNT(1) FROM {0}", tableName); 
    object count = command.ExecuteScalar(); 
    System.Diagnostics.Trace.WriteLine(count.GetType()); 
    int iCount = (int)count; //statement 1 
} 

El tiempo de ejecución de count ciertamente no es int. Es por eso que obtienes el InvalidCastException. Cuando desempaquetas un tipo de valor, debes desempaquetarlo en el tipo real de la variable. Solo después de desempaquetar puede lanzar al int.

Tenga en cuenta que la declaración 1 sigue fallando en este fragmento de código, pero ahora puede determinar el tipo real del escalar devuelto.

+0

command.ExecuteScalar() devuelve un objeto sin diferencia si asigné al objeto y luego unboxed o directamente unboxed igual –

+0

si es así no tendría sentido intentar unbox algo que es un objeto. Lo que intentaba decir es que debería intentar determinar el tipo de tiempo de ejecución del valor de retorno 'ExecuteScalar()'. El tipo estático es obviamente 'objeto', estamos de acuerdo con esto. Ahora, ¿qué está escrito en su salida cuando 'System.Diagnostics.Trace.WriteLine (count.GetType());' se ejecuta? – Seb

5

Suspiro, ejecutar escalar devuelve un int64 largo, ya que al escribir el comando SQL, sabe que el valor de retorno va a ser un número entero calculado (SELECT COUNT (..., también SELECT MAX (...

ignorar el otro consejo, todo lo que necesita es un yeso. (NO estos comandos nunca volverán una cadena, es decir, "42")

int count = (int)(long)command.ExecuteScalar(); 

o si preocupado por un gran número

long count = (long)command.ExecuteScalar(); 

A menos que, fo Hay alguna razón extraña por la que no tienes control sobre la instrucción SQL que se está ejecutando, por qué complicar las cosas con Convert o boxing/unboxing. Good greif people, K.I.S.S., abajo con código hinchado, ... y simplemente responden la pregunta.

+0

Verificado esta respuesta funciona para la pregunta formulada. –

0

Según el documento SqlCommand.ExecuteScalar Method devuelve nulo si el resultado está vacío. No puedes convertir null en int.

Sin embargo, desde mi experiencia, también puede devolver el tipo de decimal en algunos casos. Pero esto no está documentado en esa página. Entonces use Convert.ToInt32 es una opción más segura.

+0

Es altamente improbable que "COUNT (1)" vuelva a ser nulo. –

Cuestiones relacionadas