Le code suivant donne une erreur - "Aucune conversion implicite de DBnull en int."
SqlParameter[] parameters = new SqlParameter[1];
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex;
parameters[0] = planIndexParameter;
Le problème est que l'opérateur ?:
ne peut pas déterminer le type de retour car vous renvoyez une valeur int
ou une valeur de type DBNull, qui ne sont pas compatibles.
Vous pouvez bien sûr convertir l'instance de AgeIndex en type object
, ce qui satisferait l'exigence ?:
.
Vous pouvez utiliser l'opérateur ??
null-coalescing comme suit
SqlParameter[] parameters = new SqlParameter[1];
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = (object)AgeItem.AgeIndex ?? DBNull.Value;
parameters[0] = planIndexParameter;
Voici une citation de la documentation MSDN pour l'opérateur ?:
qui explique le problème
Soit les types first_expression et second_expression doivent être identiques, soit une conversion implicite doit exister d'un type à l'autre.
La réponse acceptée suggère d'utiliser un casting. Cependant, la plupart des types SQL ont un champ Null spécial qui peut être utilisé pour éviter cette conversion.
Par exemple, SqlInt32.Null
"Représente un DBNull pouvant être affecté à cette instance de la classe SqlInt32."
int? example = null;
object exampleCast = (object) example ?? DBNull.Value;
object exampleNoCast = example ?? SqlInt32.Null;
Vous devez transmettre DBNull.Value en tant que paramètre null dans SQLCommand, sauf si une valeur par défaut est spécifiée dans la procédure stockée (si vous utilisez une procédure stockée). La meilleure approche consiste à affecter DBNull.Value à tout paramètre manquant avant l'exécution de la requête. Le suivi de foreach fera le travail.
foreach (SqlParameter parameter in sqlCmd.Parameters)
{
if (parameter.Value == null)
{
parameter.Value = DBNull.Value;
}
}
Sinon changez cette ligne:
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex;
Comme suit:
if (AgeItem.AgeIndex== null)
planIndexParameter.Value = DBNull.Value;
else
planIndexParameter.Value = AgeItem.AgeIndex;
Parce que vous ne pouvez pas utiliser différents types de valeurs dans une instruction conditionnelle, car DBNull et int sont différents. J'espère que cela aidera.
Avec une ligne de code, essayez ceci:
var piParameter = new SqlParameter("@AgeIndex", AgeItem.AgeIndex ?? (object)DBNull.Value);
Essaye ça:
SqlParameter[] parameters = new SqlParameter[1];
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.IsNullable = true; // Add this line
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex== ;
parameters[0] = planIndexParameter;
Si vous utilisez l'opérateur conditionnel (ternaire), le compilateur a besoin d'une conversion implicite entre les deux types, sinon vous obtenez une exception.
Vous pouvez donc résoudre ce problème en lançant l’un des deux en System.Object
:
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : (object) AgeItem.AgeIndex;
Mais comme le résultat n’est pas vraiment joli et que vous devez toujours vous rappeler ce casting, vous pouvez utiliser une telle méthode d’extension:
public static object GetDBNullOrValue<T>(this T val)
{
bool isDbNull = true;
Type t = typeof(T);
if (Nullable.GetUnderlyingType(t) != null)
isDbNull = EqualityComparer<T>.Default.Equals(default(T), val);
else if (t.IsValueType)
isDbNull = false;
else
isDbNull = val == null;
return isDbNull ? DBNull.Value : (object) val;
}
Ensuite, vous pouvez utiliser ce code concis:
planIndexParameter.Value = AgeItem.AgeIndex.GetDBNullOrValue();
À mon avis, la meilleure solution consiste à utiliser la propriété Parameters de la SqlCommand class
public static void AddCommandParameter(SqlCommand myCommand)
{
myCommand.Parameters.AddWithValue(
"@AgeIndex",
(AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex);
}
Pensez à utiliser la structure Nullable (T) disponible. Cela vous permettra de définir des valeurs uniquement si vous les avez, et vos objets de commande SQL reconnaîtront la valeur nullable et le traiteront en conséquence, sans tracas de votre part.
if (AgeItem.AgeIndex== null)
cmd.Parameters.Add(new SqlParameter("ParaMeterName", SqlDbType.DateTime).Value = DBNull);
else
cmd.Parameters.Add(new SqlParameter("ParaMeterName", SqlDbType.DateTime).Value = AgeItem.AgeIndex);
dynamic psd = DBNull.Value;
if (schedule.pushScheduleDate > DateTime.MinValue)
{
psd = schedule.pushScheduleDate;
}
sql.DBController.RunGeneralStoredProcedureNonQuery("SchedulePush",
new string[] { "@PushScheduleDate"},
new object[] { psd }, 10, "PushCenter");
Une méthode d'extension simple pour cela serait:
public static void AddParameter(this SqlCommand sqlCommand, string parameterName,
SqlDbType sqlDbType, object item)
{
sqlCommand.Parameters.Add(parameterName, sqlDbType).Value = item ?? DBNull.Value;
}
Essaye ça:
if (AgeItem.AgeIndex != null)
{
SqlParameter[] parameters = new SqlParameter[1];
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = AgeItem.AgeIndex;
parameters[0] = planIndexParameter;
}
En d'autres termes, si le paramètre est null, n'envoyez pas simplement à votre proc stocké (en supposant bien sûr que le proc stocké accepte les paramètres nuls, ce qui est implicite dans votre question).
if (_id_categoria_padre > 0)
{
objComando.Parameters.Add("id_categoria_padre", SqlDbType.Int).Value = _id_categoria_padre;
}
else
{
objComando.Parameters.Add("id_categoria_padre", DBNull.Value).Value = DBNull.Value;
}
J'utilise une méthode simple avec un contrôle nul.
public SqlParameter GetNullableParameter(string parameterName, object value)
{
if (value != null)
{
return new SqlParameter(parameterName, value);
}
else
{
return new SqlParameter(parameterName, DBNull.Value);
}
}
essayez quelque chose comme ça:
if (_id_categoria_padre > 0)
{
objComando.Parameters.Add("id_categoria_padre", SqlDbType.Int).Value = _id_categoria_padre;
}
else
{
objComando.Parameters.Add("id_categoria_padre", DBNull.Value).Value = DBNull.Value;
}
Mon code, travaillant dans un projet réel Regardez l'opérateur ternaire avant de faire le sqlparameter C'est la meilleure façon pour moi, avec vos problèmes:
public bool Key_AddExisting
(
string clave
, int? idHito_FileServer
, int? idTipoDocumental_Almacen
, string tipoExp_CHJ
, int idTipoExp_Verti2
, int idMov_Verti2
)
{
List<SqlParameter> pars = new List<SqlParameter>()
{
new SqlParameter { ParameterName = "@Clave", Value = clave }
LOOK -> , idHito_FileServer == null ? new SqlParameter { ParameterName = "@IdHito_FileServer", Value = DBNull.Value } : new SqlParameter { ParameterName = "@IdHito_FileServer", Value = idHito_FileServer }
LOOK -> , idTipoDocumental_Almacen == null ? new SqlParameter { ParameterName = "@IdTipoDocumental_Almacen", Value = DBNull.Value } : new SqlParameter { ParameterName = "@IdTipoDocumental_Almacen", Value = idTipoDocumental_Almacen }
, new SqlParameter { ParameterName = "@TipoExp_CHJ", Value = tipoExp_CHJ }
, new SqlParameter { ParameterName = "@IdTipoExp_Verti2", Value = idTipoExp_Verti2 }
, new SqlParameter { ParameterName = "@IdMov_Verti2", Value = idMov_Verti2 }
};
string sql = "INSERT INTO [dbo].[Enlaces_ClavesCHJ_MovimientosVerti2] " +
"( " +
" [Clave] " +
", [IdHito_FileServer] " +
", [IdTipoDocumental_Almacen] " +
", [TipoExp_CHJ] " +
", [IdTipoExp_Verti2] " +
", [IdMov_Verti2] " +
") " +
"VALUES" +
"( " +
" @Clave" +
", @IdHito_FileServer" +
", @IdTipoDocumental_Almacen" +
", @TipoExp_CHJ" +
", @IdTipoExp_Verti2" +
", @IdMov_Verti2" +
")";
return DbBasic.ExecNonQuery(ref this.conn, sql, pars);
}
int? nullableValue = null;
object nullableValueDB
{
get{
if(nullableValue==null)
return DBNull.Value;
else
return (int)nullableValue;
}
}
Je résous comme ça.
C'est ce que je fais tout simplement ...
var PhoneParam = new SqlParameter("@Phone", DBNull.Value);
if (user.User_Info_Phone != null)
{
PhoneParam.SqlValue = user.User_Info_Phone;
}
return this.Database.SqlQuery<CustLogonDM>("UpdateUserInfo @UserName, @NameLast, @NameMiddle, @NameFirst, @Address, @City, @State, @PostalCode, @Phone",
UserNameParam, NameLastParam, NameMiddleParam, NameFirstParam, AddressParam, CityParam, StateParam, PostalParam, PhoneParam).Single();