Système.InvalidCastException: l'Objet ne peut pas être lancé à partir de DBNull à d'autres types de
J'ai une exception dans mon code. J'ai déjà essayé de changer mon int64 int32 mais cela ne veut pas changer.
Dans la base de données, les cellules qui représentent "column_ID" ont le type de données NOMBRE.
Le problème est à la ligne 7 du présent code:
private void dataGridView_ArticleINVIA_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0 && e.RowIndex <= (sender as DataGridView).Rows.Count - 1)
{
try
{
Int64 id_riga = Convert.ToInt64((sender as DataGridView).Rows[e.RowIndex].Cells["column_ID"].Value);
//Exception thrown here:
int id_macchina = Convert.ToInt32((sender as
DataGridView).Rows[e.RowIndex].Cells["column_Machine"].Value);
FormRecipeNote PopUpNote = new FormRecipeNote(id_macchina,
"MODIFICA", id_riga, 0);
PopUpNote.ShowDialog(this);
PopUpNote.Dispose();
}
catch (Exception Exc)
{
FormMain.loggerSoftwareClient.Trace(this.Name + " " + Exc);
}
//DataGrid_ArticleINVIA();
}
}
l'erreur est:
System.InvalidCastException: Object cannot be cast from DBNull to other types.
at System.DBNull.System.IConvertible.ToInt64(IFormatProvider provider)
at System.Convert.ToInt64(Object value)
at Software_Client.FormSendReceiveRecipe.dataGridView_ArticleINVIA_CellDoubleClick(Object sender, DataGridViewCellEventArgs e)
Quelqu'un peut-il m'aider à résoudre ce problème?
- L'exception est vous dire exactement ce que vous devez savoir -
Rows[e.RowIndex].Cells["column_Machine"].Value
estDbNull
, et vous ne pouvez pas jeterDbNull
de tout autre type. Vérifiez si votrecolumn_Machine
cellule estDbNull
avant d'appelerConvert.ToInt32
- Tu veux dire que j'ai seulement besoin de vérifier si la valeur est DbNull? et si il ainsi? j'ai vérifié sur la base de données de la valeur et n'est pas NULL
- Correct, il n'est pas
null
, c'estDBNull
. Les deux sont différents. - En règle générale, si vous pouvez appeler Disposer sur un objet, vous devez l'entourer d'une aide du bloc:
using (FormRecipeNote PopUpNote = new FormRecipeNote(id_macchina, "MODIFICA", id_riga, 0)) { PopUpNote.ShowDialog(this); }
Vous devez vous connecter pour publier un commentaire.
Que le message d'erreur dit, la valeur de la cellule est
DBNull.Value
et il ne peut pas convertir à partir de ce que vous voulez qu'il soit (dans ce cas, unlong
ou unint
). Vous avez besoin de vérifier pourDBNull
avant la conversion/casting le nombre:Parce que cela ajoute un peu ennuyeux, les frais généraux, si vous le faites bien, vous aurez probablement envie de faire un helper qui le fait pour vous.
Puis votre code peut être:
Vous pouvez modifier la ligne problématique à :
Ce que va donner la valeur par défaut de type int (0) à la variable
id_macchina
si la valeur de la colonnecolumn_Machine
est null dans la base de données seraDBNull
en C#)Essayez ceci:
Il va fonctionner! la valeur sera 0 si la colonne est
DBNull
.* EDIT *
Mais essayez d'utiliser quelque chose d'autre, cela peut cacher quelques bugs, comme la modification du type de données, si le type est long et pas un int dans la base de données, sera toujours affecter 0 à la variable, il s'est passé avec moi dans le passé, grâce à @hvd à indiquer que, dans son commentaire.
int
, c'est à l'aide deDBNull
au lieu denull
.DBNull
ne peut pas être convertie àint?
.DBNull
n'est pas de typeint
ouint?
la conversion échoue, et le résultat deas
est qu'il renvoienull
tandis qu'une réelleint
succès de la fonte. Cependant, il est assez déroutant, car il donne la fausse impression que cela ne fonctionne pas, et il n'est pas clair ce qu'il fait réellement, de sorte que la lisibilité souffre considérablement.DBNull.Value as int?
, qui n'a pas fonctionné, mais c'est différent (car la valeur est de typeobject
).null
.long
) commenull
est un bon point, cependant.int?
(akaNullable<int>
) si vous allez juste pour appeler GetValueOrDefault() sur celui-ci. C'est un exercice simple à écrire une belle & pratique de la méthode d'extension pour faire exactement la même chose, mais avec beaucoup plus de sémantique simple. Vous pouvez même aller plus loin dans la méthode d'extension pour faire plus de la vérification des erreurs, etc pour les objets qui ne sont pas égaux à DBNull ni convertibles pour le type désiré. OMI ces cas ne devraient pas être ignorées silencieusement, comme ils le seraient en appelantas int?
etc.int?
et si elle fonctionne et si c'est une bonne idée ou pas, c'est complètement hors sujet. Ce n'est vraiment rien pour l'OP qui est tout simplement à essayer de comprendre pourquoi DBNull s'affiche dans la cellule lorsque la base de données réelle valeur n'EST PAS NULL (au moins autant que l'on peut dire). De sorte qu'il pourrait être plus utile pour l'aider à aller vers le bas de son vrai problème plutôt que de débattre sur le meilleur modèle à utiliser pour détecter & convertir DBNulls. La question est de savoir POURQUOI la cellule Null/DBNull en premier lieu, et comment les OP à trouver l'origine du bug.Je suis un peu confus par certains de vos commentaires. Comme par exemple, dans votre code, le commentaire indique que la ligne contenant
ToInt32
est où l'erreur se produit, mais le message d'erreur indique clairement que l'erreur est générée à partir deToInt64
.Aussi, vous avez dit que la valeur dans la base de données n'est PAS nulle. Si cela est vrai, vous n'obtiendrez pas la valeur DBNull, de sorte qu'il peut être intéressant d'élargir votre code un peu de sorte que vous pouvez afin que vous pouvez placer des points d'arrêt et d'inspecter les valeurs dans les cellules directement avant d'essayer de les convertir.
J'ai posté un exemple de code ci-dessous que vous pouvez utiliser, y compris une conversion d'une fonction d'assistance que vous pourriez trouver utiles.
Je tiens également à préciser un commentaire que j'ai vu ci-dessus que m'a dit "...il n'est pas null, il est DBNull. Les deux sont différents". Cette affirmation est vraie en général, en C#, cependant c'est en fait trompeur dans le contexte qu'il a été écrit. Il a été écrit en réponse au commentaire précédent qui dit que "[I] vérifiée sur la base de données de la valeur et n'est pas NULLE". Pour plus de précisions, une valeur NULL dans un champ de base de données EST représentée par DBNull dans la plupart des .Net, base de données des fournisseurs. Donc, en fait, une valeur NULL dans la base de données EST généralement le même que DBNull en C#. Donc, si l'OP est correct de dire que la base de données de la valeur n'est PAS NULL, alors il ne suivre que la valeur de la cellule ne doit pas être DBNull.
Bien sûr, il est toujours vrai que
null
n'est pas le même queDBNull
, afin de vérifier si un objet est null n'est pas de déterminer s'il est DBNull ou pas, (mais ce n'est pas ce que l'OP a dit).Comme note finale, l'extension de la méthode que j'ai écrit,
FromDB
, inclut un paramètre facultatif pour une valeur de retour par défaut dans le cas où l'objet passé est DBNull.Ceci peut être utilisé comme suit:
En fonction de vos propres préférences personnelles ci-dessus paradigme pourrait être plus facile à comprendre que la Nullable version décrite dans d'autres réponses.