问题描述
int i = 5;
string query = "select col1 from table where col2 = @prm1 and col3 = @prm2";
sqlCommand cmd = new sqlCommand(query,connection);
cmd.Parameters.Add(new sqlParameter("@prm1",(int)MyEnum.val1));
cmd.Parameters.Add(new sqlParameter("@prm2",i);
public enum MyEnum
{
val1 = 0,val2 = 100,val3 = 150
}
现在,内置类sqlParameter
具有2个参数的2个重载方法,如下所示:
public sqlParameter(string parameterName,sqlDbType dbType);
public sqlParameter(string parameterName,object value);
现在,对于@prm2
,我正在传递int
变量,它可以正确地初始化具有正确值的参数。但是对于@prm1
,我在传递枚举并将其转换为int
作为值时,将其作为sqlParameter
的第一种方法。
内置sqlDbType
枚举如下:
public enum sqlDbType
{
BigInt = 0,Binary = 1,....
....
}
由于我传递的枚举的值为0
,因此它将采用0,并使用第一种方法并使用BigInt
DATATYPE创建参数,而不是使用值0
创建参数。
这可能是什么原因?是某种错误还是我在这里错过了一些愚蠢的观点?
更新:尽管this为我的原始问题提供了答案,即“ 0可隐式转换为枚举,但非零值不是”,因此选择方法的不同对于两个语句。我尝试了以下操作:
cmd.Parameters.Add(new sqlParameter("@prm1",(int)MyEnum.val1));
cmd.Parameters.Add(new sqlParameter("@prm1",Convert.ToInt32(MyEnum.val1)));
使用sqlDbType
arg的第一条语句调用方法和使用第二条调用具有object
值的方法,即使我基本上将两个值都作为int
传递。有什么解释吗?
解决方法
我认为API有点笨拙。只需明确指定即可:
cmd.Parameters.Add(new SqlParameter("@prm1",SqlDbType.Int){ Value = (int)MyEnum.val1}));
如果不使用任何ORM或框架来构建SQL,我通常将其替换为扩展名:
public static class SqlExtensions
{
public static SqlParameterCollection Add(this SqlParameterCollection pars,string name,SqlDbType type,object value)
{
var res = new SqlParameter(name,type){Value = (value == null ? DbNull.Value)};
pars.Add(res);
return pars;
}
}
然后:
cmd.Parameters.Add("@a",SqlDbType.Int,123)
.Add("@b",SqlDbType.BigInt,234)
.Add("@c",SqlDbType.Binary,null);