J'ai joué avec SQL et les bases de données en C # via SqlCeConnection . J'utilise ExecuteReader pour lire les résultats et BigInt les valeurs des ID d'enregistrement qui sont lus dans Longs.
Aujourd'hui, je joue avec des instructions SQL qui utilisent des instructions basées sur COUNT ('SELECT COUNT (*) FROM X') et j'utilise ExecuteScalar pour lire ces résultats à valeur unique.
Cependant, j'ai rencontré un problème. Je n'arrive pas à stocker les valeurs dans un type de données Long, que j'utilisais jusqu'à présent. Je peux les stocker dans Int64.
J'utilise BigInt pour les ID d'enregistrement afin d'obtenir le nombre maximal potentiel d'enregistrements.
Un BigInt 8 octets est donc un Int64. Un Long n'est-il pas égal à un Int64 car les deux sont des entiers signés 64 bits?
Par conséquent, pourquoi ne puis-je pas convertir un Int64 en un Long?
long recordCount =0;
recordCount = (long)selectCommand.ExecuteScalar();
L'erreur est:
La distribution spécifiée n'est pas valide.
Je peux lire un BigInt dans un Long. Ce n'est pas un problème. Je ne peux pas lire un SQL COUNT en long.
COUNT renvoie un Int (Int32), donc le problème est en fait de convertir un Int32 en un long.
long
est Int64
en .NET ; c'est juste un alias en C #. Votre problème consiste à convertir la valeur de retour en long
et à moins que nous connaissions le type de retour de votre requête avec certitude, nous ne saurions pas pourquoi vous obtenez une erreur. SQL BigInt doit être convertible en long
.
Si c'est le COUNT (*) qui revient, alors c'est Int32. Vous devez utiliser la classe Convert
:
long l = Convert.ToInt64(selectCommand.ExecuteScalar());
Si vous pensez que vos comptes vont déborder d'un int/Int32, vous devez utiliser COUNT_BIG () dans votre SQL à la place - il a le bon type de retour.
Quant à savoir pourquoi les lancers ne fonctionnent pas, je ne suis pas sûr. Le C # suivant:
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
long lCount = (long)cmd.ExecuteScalar();
Int64 iCount = (Int64)cmd.ExecuteScalar();
Compile à cet IL:
L_0000: nop
L_0001: newobj instance void [System.Data]System.Data.SqlClient.SqlCommand::.ctor()
L_0006: stloc.0
L_0007: ldloc.0
L_0008: callvirt instance object [System.Data]System.Data.Common.DbCommand::ExecuteScalar()
L_000d: unbox.any int64
L_0012: stloc.1
L_0013: ldloc.0
L_0014: callvirt instance object [System.Data]System.Data.Common.DbCommand::ExecuteScalar()
L_0019: unbox.any int64
L_001e: stloc.2
L_001f: ret
Autrement dit, ils semblent compiler en code identique.