J'ai l'erreur ci-dessus dans mon application. Voici le code original
public string GetCustomerNumber(Guid id)
{
string accountNumber =
(string)DBSqlHelperFactory.ExecuteScalar(connectionStringSplendidmyApp,
CommandType.StoredProcedure,
"GetCustomerNumber",
new SqlParameter("@id", id));
return accountNumber.ToString();
}
J'ai remplacé par
public string GetCustomerNumber(Guid id)
{
object accountNumber =
(object)DBSqlHelperFactory.ExecuteScalar(connectionStringSplendidCRM,
CommandType.StoredProcedure,
"spx_GetCustomerNumber",
new SqlParameter("@id", id));
if (accountNumber is System.DBNull)
{
return string.Empty;
}
else
{
return accountNumber.ToString();
}
}
Y a-t-il une meilleure façon de contourner cela?
Un formulaire plus court peut être utilisé:
return (accountNumber == DBNull.Value) ? string.Empty : accountNumber.ToString()
EDIT: N'a pas fait attention à ExecuteScalar. Il renvoie vraiment null si le champ est absent du résultat. Alors utilisez plutôt:
return (accountNumber == null) ? string.Empty : accountNumber.ToString()
Avec une fonction générique simple, vous pouvez rendre cela très facile. Faites juste ceci:
return ConvertFromDBVal<string>(accountNumber);
en utilisant la fonction:
public static T ConvertFromDBVal<T>(object obj)
{
if (obj == null || obj == DBNull.Value)
{
return default(T); // returns the default value for the type
}
else
{
return (T)obj;
}
}
ExecuteScalar retournera
Si vous savez que la première colonne du résultat est une chaîne, pour couvrir toutes les bases, vous devez rechercher null et DBNull. Quelque chose comme:
object accountNumber = ...ExecuteScalar(...);
return (accountNumber == null) ? String.Empty : accountNumber.ToString();
Le code ci-dessus repose sur le fait que DBNull.ToString renvoie une chaîne vide.
Si accountNumber est un autre type (par exemple, un entier), vous devez être plus explicite:
object accountNumber = ...ExecuteScalar(...);
return (accountNumber == null || Convert.IsDBNull(accountNumber) ?
(int) accountNumber : 0;
Si vous êtes certain que votre jeu de résultats comportera toujours au moins une ligne (par exemple, SELECT COUNT (*) ...), vous pouvez ignorer la vérification de la valeur null.
Dans votre cas, le message d'erreur "Impossible de convertir un objet de type 'System.DBNull' en un type 'System.String`" indique que la première colonne de votre jeu de résultats est une valeur DBNUll. Ceci est du casting à la chaîne sur la première ligne:
string accountNumber = (string) ... ExecuteScalar(...);
Marc_s a déclaré qu'il n'était pas nécessaire de rechercher DBNull.Value.
Vous pouvez utiliser l'opérateur de coalescence nul de C #
return accountNumber ?? string.Empty;
C'est la méthode générique que j'utilise pour convertir tout objet pouvant être un fichier DBNull.Value
public static T ConvertDBNull<T>(object value, Func<object, T> conversionFunction)
{
return conversionFunction(value == DBNull.Value ? null : value);
}
usage:
var result = command.ExecuteScalar();
return result.ConvertDBNull(Convert.ToInt32);
plus court:
return command
.ExecuteScalar()
.ConvertDBNull(Convert.ToInt32);
Il existe un autre moyen de résoudre ce problème. Que diriez-vous de modifier votre procédure de magasin? En utilisant ISNULL (votre champ, "") fonction SQL, vous pouvez renvoyer une chaîne vide si la valeur de retour est null.
Ensuite, vous avez votre code propre en version originale.
Je suppose que tu peux le faire comme ça:
string accountNumber = DBSqlHelperFactory.ExecuteScalar(...) as string;
Si accountNumber est null, cela signifie que DBNull n'est pas une chaîne :)
String.Concat transforme les valeurs DBNull et null en une chaîne vide.
public string GetCustomerNumber(Guid id)
{
object accountNumber =
(object)DBSqlHelperFactory.ExecuteScalar(connectionStringSplendidCRM,
CommandType.StoredProcedure,
"spx_GetCustomerNumber",
new SqlParameter("@id", id));
return String.Concat(accountNumber);
}
Cependant, je pense que vous perdez quelque chose sur la compréhensibilité du code