Parameters.Add和Parameters.AddWithValue之间的区别

我读了这里的MSDN文档和示例,并且我知道Paramters.Add调用的正确语法是:

  command.Parameters.Add("@ID", SqlDbType.Int); command.Parameters["@ID"].Value = customerID; 

您必须指定参数名称, SqlDbType和值与.Value

现在,一个Parameters.AddWithValue调用的正确语法是:

  command.Parameters.AddWithValue("@demographics", demoXml); 

单行并跳过Type部分。

我的问题是:当我这样做的时候,

  command.Parameters.Add("@demographics", demoXml); // .Add method with .AddWithValue syntax 

我没有得到任何编译错误,甚至更怪,当代码执行时,一切似乎正常工作?

在function方面没有区别。 事实上,两者都是这样做的:

 return this.Add(new SqlParameter(parameterName, value)); 

他们之所以推荐使用AddWithValue是因为它增加了额外的清晰度,另外还因为第二个参数是object ,这使得对于一些重载Add被调用的人来说,它并不是立即就显而易见的,并且导致了非常不同的结果行为。

看看这个例子:

  SqlCommand command = new SqlCommand(); command.Parameters.Add("@name", 0); 

乍一看,它看起来像是调用Add(string name, object value)重载, 但它不是 。 它调用Add(string name, SqlDbType type)重载! 这是因为0可以隐式转换为枚举types。 所以这两行:

  command.Parameters.Add("@name", 0); 

  command.Parameters.Add("@name", 1); 

实际上导致两种不同的方法被调用。 1不能隐式转换为枚举,所以select了object重载。 用0select枚举超载。

不同之处在于使用AddWithValue时的隐式转换。 如果你知道你正在执行的SQL查询(存储过程)正在接受一个int,nvarchar等types的值,没有必要在代码中重新声明它。

对于复杂types的场景(例如DateTime,float),我可能会使用Add,因为它更直接,但AddWithValue适用于更直接的types场景(Int to Int)。

没有显式地提供types,如command.Parameters.Add("@ID", SqlDbType.Int); ,它会尝试隐含地将input转换成它所期望的。

不足之处在于,隐式转换可能不是最佳转换,可能会导致性能下降。

这里有一个关于这个话题的讨论: http : //forums.asp.net/t/1200255.aspx/1

当我们使用CommandObj.Parameter.Add()时,首先需要2个参数是过程参数,其次是它的数据types,但是.AddWithValue()首先取2个参数是过程参数,其次是数据variables

 CommandObj.Parameter.Add("@ID",SqlDbType.Int).Value=textBox1.Text; 

//为.AddWithValue

 CommandObj.Parameter.AddWitheValue("@ID",textBox1.Text); 

其中ID是数据types为Int的存储过程的参数