![](/img/trans.png)
[英]How to assign a value to sqlparameter NULL values without checking for null or 0?
[英]Assign null to a SqlParameter
下面的代码给出了一个错误——“没有从 DBnull 到 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;
问题是?:
运算符无法确定返回类型,因为您返回的是不兼容的int
值或 DBNull 类型的值。
您当然可以将 AgeIndex 的实例转换为满足?:
要求的类型object
。
你可以使用??
空合并运算符如下
SqlParameter[] parameters = new SqlParameter[1];
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = (object)AgeItem.AgeIndex ?? DBNull.Value;
parameters[0] = planIndexParameter;
这是MSDN 文档中对?:
运算符的引用,它解释了问题
first_expression 和 second_expression 的类型必须相同,或者必须存在从一种类型到另一种类型的隐式转换。
公认的答案建议使用演员表。 但是,大多数 SQL 类型都有一个特殊的 Null 字段,可以用来避免这种强制转换。
例如, SqlInt32.Null
“表示可以分配给此 SqlInt32 类实例的 DBNull。”
int? example = null;
object exampleCast = (object) example ?? DBNull.Value;
object exampleNoCast = example ?? SqlInt32.Null;
您需要在 SQLCommand 中将DBNull.Value
作为 null 参数传递,除非在存储过程中指定了默认值(如果您使用的是存储过程)。 最好的方法是在查询执行之前为任何缺少的参数分配DBNull.Value
,然后 foreach 将完成这项工作。
foreach (SqlParameter parameter in sqlCmd.Parameters)
{
if (parameter.Value == null)
{
parameter.Value = DBNull.Value;
}
}
否则更改此行:
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex;
如下:
if (AgeItem.AgeIndex== null)
planIndexParameter.Value = DBNull.Value;
else
planIndexParameter.Value = AgeItem.AgeIndex;
因为您不能在条件语句中使用不同类型的值,因为 DBNull 和 int 彼此不同。 希望这会有所帮助。
用一行代码,试试这个:
var piParameter = new SqlParameter("@AgeIndex", AgeItem.AgeIndex ?? (object)DBNull.Value);
如果使用条件(三元)运算符,编译器需要在两种类型之间进行隐式转换,否则会出现异常。
因此,您可以通过将两者之一转换为System.Object
来修复它:
planIndexParameter.Value = (AgeItem.AgeIndex== null) ? DBNull.Value : (object) AgeItem.AgeIndex;
但是由于结果不是很漂亮,而且你总是要记住这个转换,你可以使用这样的扩展方法:
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;
}
然后你可以使用这个简洁的代码:
planIndexParameter.Value = AgeItem.AgeIndex.GetDBNullOrValue();
尝试这个:
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;
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;
}
考虑使用可用的 Nullable(T) 结构。 它只会让你设置值,如果你有它们,你的 SQL Command 对象将识别可以为空的值并相应地进行处理,而不会有任何麻烦。
一个简单的扩展方法是:
public static void AddParameter(this SqlCommand sqlCommand, string parameterName,
SqlDbType sqlDbType, object item)
{
sqlCommand.Parameters.Add(parameterName, sqlDbType).Value = item ?? DBNull.Value;
}
我使用带有空检查的简单方法。
public SqlParameter GetNullableParameter(string parameterName, object value)
{
if (value != null)
{
return new SqlParameter(parameterName, value);
}
else
{
return new SqlParameter(parameterName, DBNull.Value);
}
}
尝试这个:
if (AgeItem.AgeIndex != null)
{
SqlParameter[] parameters = new SqlParameter[1];
SqlParameter planIndexParameter = new SqlParameter("@AgeIndex", SqlDbType.Int);
planIndexParameter.Value = AgeItem.AgeIndex;
parameters[0] = planIndexParameter;
}
换句话说,如果参数为空,则不要将其发送到您的存储过程(当然,假设存储过程接受您的问题中隐含的空参数)。
在我看来,更好的方法是使用SqlCommand类的Parameters属性来做到这一点:
public static void AddCommandParameter(SqlCommand myCommand)
{
myCommand.Parameters.AddWithValue(
"@AgeIndex",
(AgeItem.AgeIndex== null) ? DBNull.Value : AgeItem.AgeIndex);
}
我的代码,在实际项目中工作 在制作 sqlparameter 之前查看三元运算符,这对我来说是最好的方法,没有问题:
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);
}
你可以做这样的事情。 这里startDate和endDate是可为空的日期时间参数
var Statistics= db.Database.SqlQuery<ViewStatistics>("YourStoreProcedure_Or_sqlQuery @startDate,@endDate",
new SqlParameter("startDate", startDate?? (object)DBNull.Value),
new SqlParameter("endDate", endDate?? (object)DBNull.Value)
).ToList();
尝试这样的事情:
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;
}
int? nullableValue = null;
object nullableValueDB
{
get{
if(nullableValue==null)
return DBNull.Value;
else
return (int)nullableValue;
}
}
我就是这样解决的。
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);
这就是我所做的...
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();
dynamic psd = DBNull.Value;
if (schedule.pushScheduleDate > DateTime.MinValue)
{
psd = schedule.pushScheduleDate;
}
sql.DBController.RunGeneralStoredProcedureNonQuery("SchedulePush",
new string[] { "@PushScheduleDate"},
new object[] { psd }, 10, "PushCenter");
sqlCom.Parameters.Add(new SqlParameter("@qavCode", SqlDbType.Char, 11)).Value = (object)(string.IsNullOrEmpty(rf.Request.QavCode) ? null : rf.Request.QavCode) ?? DBNull.Value;
改进空合并运算符的使用 ?? 为了在我的示例中管理空字符串,我将常规三元 ?: 与空合并运算符 ?? 混合在一起。 希望我的建议有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.