Réglage du paramètre de DBNull.Valeur à l'aide ternaire donne une erreur de syntaxe?
J'ai le code suivant pour définir un paramètre qui sera utilisé dans une instruction INSERT pour définir une colonne de type VARCHAR dans une base de données SQL Server. Mon objet de valeur (du nom de l'oit) a une propriété appelée la Description qui est initialisé à la Chaîne.Vide, puis obtient une valeur de lire du XML, ou si cet élément XML est vide, il reste simplement comme une Chaîne de caractères.Vide.
Donc, lors de l'insertion dans la base de données, si le bien est toujours à la Chaîne.Vide, j'aimerais l'avoir à insérer une valeur null.
database.AddInParameter(cmd, "@description", DbType.String,
(ilo.Description.Equals(string.Empty)) ?
DBNull.Value :
ilo.Description);
Donc, fondamentalement, je veux dire, si l'oit.La Description est égal à la chaîne.vide, définissez le paramètre sur DBNull.Valeur, sinon il à l'oit.Description de l'.
Cela donne l'erreur suivante dans Visual Studio...
Erreur 141 Type d'expression conditionnelle ne peut pas être déterminé, car il n'y a pas de conversion implicite entre "Système".DBNull' et 'string'
Pourquoi?
La partie la plus curieuse est que je peux effectuer les opérations suivantes avec pas d'erreur, qui doit être exactement la même chose qu'à l'aide inline conditionnelle de la syntaxe, comme ci-dessus!?!
if(ilo.Description.Equals(string.Empty))
{
database.AddInParameter(cmd, "@description", DbType.String, DBNull.Value);
}
else
{
database.AddInParameter(cmd, "@description", DbType.String, ilo.Description);
}
J'ai cherché sur d'autres posts, et trouvé celui-ci, mais il n'a pas vraiment répondu à ma question.
EntLib Moyen de Lier Valeur "Null pour le Paramètre
Je suis plus intéressé par POURQUOI, parce qu'à l'évidence la solution de contournement est d'utiliser un if/else au lieu de la ligne (ternaire) de la syntaxe?
Il y a une réponse à ce lien, mais j'aimerais une meilleure explication, car il semble être BS pour moi que cela ne fonctionne pas; j'appellerais cela un bug!
http://msdn.microsoft.com/en-us/library/ty67wk28.aspx
Merci Steve. Votre lien est ce que je cherchais vraiment. Je pense que c'est une stupide aspect de .NET; pourquoi ne pas simplement d'évaluer si les types de chaque résultat possible de l'adapter à la déclaration. c'est à dire si vous dites Object o = (someBool) ? someInt32 : someString; vous obtenez une erreur, mais comment serait-il facile de l'évaluer à la fois les résultats peuvent être implicitement converti en un Objet, au lieu d'évaluer si someString peut être coulé à someInt32? Il semble stupide pour moi, mais je suppose que c'est comment il est. Merci!
J'aimerais aussi dire que je suis très impressionné par la vitesse et la précision des réponses à ce fil. Cette communauté est génial! Merci à tous!
OriginalL'auteur Jim | 2012-06-01
Vous devez vous connecter pour publier un commentaire.
C'est une erreur commune des gens de recevoir lors de l'utilisation de l'opérateur conditionnel. Pour le fixer, il suffit de jeter un ou deux résultats à un type de base.
La question est révélé dans le message d'erreur que vous avez vu.
Une chaîne de caractères n'est pas un DBNull, et un DBNull n'est pas une chaîne. Par conséquent, le compilateur ne peut pas déterminer le type de l'expression. En utilisant une fonte à un type de base (dans ce cas,
object
), vous créez un scénario où le compilateur peut déterminer que la chaîne est également convertible pour objet, de sorte que le type de l'expression peut être déterminé comme objet, aussi bien correspond avec ce que votre ligne de code s'attend également à ce que le DbParameter argument.OriginalL'auteur Anthony Pegram
C'est ce que j'ai trouvé dans un autre thread, et il a très bien fonctionné pour moi:
J'espère que cela aide.
OriginalL'auteur Sagar
Anthony est en effet correcte, de sorte qu'il devrait obtenir la bonne réponse, cependant voici une méthode d'extension parce que je m'ennuie...
utilisation de votre scénario:
Pas de soucis, après réflexion, peut-être mieux de mettre la méthode d'extension sur le ParameterCollection / base de données de l'objet lui-même de fournir un wrapper qui gère les valeurs null dans la façon dont vous le souhaitez.
OriginalL'auteur Marlon
Vous obtenez l'erreur de compilation car les deux parties de l'expression ternaire doivent être du même type. La plus simple solution de contournement pour ce problème consiste à lancer à la fois à un objet:
OriginalL'auteur Tuan