" SqlParameterCollection只接受非null的SqlParameter类型对象,而不接受String对象"

时间:2014-03-28 06:32:05

标签: c# .net sql-server database

我一直得到例外

The SqlParameterCollection only accepts non-null SqlParameter type objects, not String objects

,执行以下代码时:

string StrQuery;
            using (SqlConnection conn = new SqlConnection(@"Data Source=.\sqlexpress;Initial Catalog=SanFransiscoData;Integrated Security=True;Pooling=False"))
            {
                using (SqlCommand comm = new SqlCommand())
                {
                    comm.Connection = conn;
                    conn.Open();
                   // SqlParameter author = new SqlParameter("@author", dataGridView1.Rows[0].Cells[0].Value.ToString());
                    comm.Parameters.Add("@author", SqlDbType.VarChar);
                    comm.Parameters.Add("@title", SqlDbType.NVarChar);
                    comm.Parameters.Add("@genre", SqlDbType.VarChar);
                    comm.Parameters.Add("@price", SqlDbType.Float);
                    comm.Parameters.Add("@publish_date", SqlDbType.Date);
                    comm.Parameters.Add("@description", SqlDbType.NVarChar);
                    comm.Parameters.Add("@bookid", SqlDbType.VarChar);
                    for (int i = 0; i < dataGridView1.Rows.Count; i++)
                    {
                        StrQuery = "INSERT INTO BooksData VALUES(@author,@title,@genre,@price,@publish_date,@description,@bookid)";
                        comm.Parameters.Add(dataGridView1.Rows[i].Cells[0].Value.ToString());
                        comm.Parameters.Add(dataGridView1.Rows[i].Cells[1].Value.ToString());
                        comm.Parameters.Add(dataGridView1.Rows[i].Cells[2].Value.ToString());
                        comm.Parameters.Add(Convert.ToDecimal(dataGridView1.Rows[i].Cells[3].Value));
                        comm.Parameters.Add(Convert.ToDateTime(dataGridView1.Rows[i].Cells[4].Value));
                        comm.Parameters.Add(dataGridView1.Rows[i].Cells[5].Value.ToString());
                        comm.Parameters.Add(dataGridView1.Rows[i].Cells[6].Value.ToString());
                        comm.CommandText = StrQuery;
                        comm.ExecuteNonQuery();
                    }
                }

请告诉我哪里出错了。

10 个答案:

答案 0 :(得分:8)

我将对System.Data.SqlClient的引用替换为Microsoft.Data.SqlClient 更正了using语句,我的问题就消失了

我现在在.csproj中拥有

  <ItemGroup>
    <PackageReference Include="Microsoft.Data.SqlClient" Version="1.1.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" />
  </ItemGroup>

但是我还发现我使用了以下方案,在该方案中创建了System.Data.SqlClient.SqlParameter

    public static List<T> RunQuery<T>(ApiDbContext context, string query, Func<DbDataReader, T> map, params SqlParameter[] parameters)
    {
        var cn = context.Database.GetDbConnection();
        var oldState = cn.State;
        if (cn.State.Equals(ConnectionState.Closed)) { cn.Open(); }

        using (var command = cn.CreateCommand())
        {
            command.CommandText = query;
            command.CommandType = CommandType.Text;
            foreach (var param in parameters)
            {
                var p = new System.Data.SqlClient.SqlParameter
                {
                    ParameterName = param.ParameterName, Value = param.Value, SqlDbType = param.SqlDbType
                };
                command.Parameters.Add(p);
            }
            if (cn.State.Equals(ConnectionState.Closed)) { cn.Open(); }
            var entities = new List<T>();
            using (var result = command.ExecuteReader())
            {
                while (result.Read())
                {
                    entities.Add(map(result));
                }
            }

            if (oldState.Equals(ConnectionState.Closed) && cn.State == ConnectionState.Open) { cn.Close(); }
            return entities;
        }
    }

答案 1 :(得分:7)

我遇到了同样的错误,不得不像这样使用AddWithValue ......

cmd.Parameters.AddWithValue(@columnToUpdate, newValue);
cmd.Parameters.AddWithValue(@conditionalColumn, conditionalValue);

答案 2 :(得分:4)

我尝试了上述所有步骤,但无济于事。

最后通过更改名称空间找到并修复了它

使用System.Data.SqlClient 使用Microsoft.Data.SqlClient

Arshad

答案 3 :(得分:2)

使用Add方法时,您尝试添加新参数。你想要做的是分配价值。所以改变这个:

comm.Parameters.Add(dataGridView1.Rows[i].Cells[0].Value.ToString());

到此:

comm.Parameters["@author"].Value = dataGridView1.Rows[i].Cells[0].Value.ToString();

与其他参数类似。

答案 4 :(得分:2)

尝试以下

comm.Parameters.Add("@author", SqlDbType.VarChar);
comm.Parameters["@author"].Value = dataGridView1.Rows[i].Cells[0].Value.ToString();

答案 5 :(得分:0)

我遇到了同样的问题,但是我正在做一个对象[2] =对象[1]作为SqlParameters,类似于正在尝试的东西。

只是添加到线程中,我从这样的方法添加了这个简单的SqlParameters对象数组,

    private SqlParameter GetGenericParamsObject(string name, object data)
    {
        return new SqlParameter(name, SetSqlDataType(data.GetType().ToString())) { Direction = Input, Value = data };
    }

如果SetSqlDataType()有一个简单的开关,即SqlDbType.Int是设置它的返回类型之一。

然后我跑

    private static void ExecuteSqlCommand(DbContext dbContext, string sql, params object[] sqlParameters)
    {
        try
        {
            if (dbContext.Database.Connection.State == ConnectionState.Closed)
                dbContext.Database.Connection.Open();
            var cmd = dbContext.Database.Connection.CreateCommand();
            cmd.CommandText = sql;
            foreach (var param in sqlParameters)
                cmd.Parameters.Add(param);
            cmd.ExecuteNonQuery();
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }

这有助于转换为正确的数据类型,并将param名称,数据类型和对象移出命令方法以便于调试,然后只需将整个SqlParameter添加到cmd.Parameters。

答案 6 :(得分:0)

对于这个问题的任何以后的读者-示例涉及.Add(),但是如果使用不正确,.Remove()也会抛出此错误。正如其他人所证明的那样,使用.Add()的正确方法是:

cmd.Parameters.AddWithValue("Key", "Value");

使用.Remove()的正确方法是:

cmd.Parameters.Remove(command.Parameters["Key"]); 

答案 7 :(得分:0)

以下简单的解决方案对我有用:

SqlCommand command = ...
command.Parameters.Add(parameterPlaceholder, SqlDbType.Char);
command.Parameters[parameterPlaceholder].Value = (object)parameterValue ?? DBNull.Value;

用“DBNull.Value”替换空值是关键。在上面的示例中,不要忘记根据您的需要调整 SqlDbType。

答案 8 :(得分:0)

我在使用 System.Data.Entity.Database 时也遇到了这个错误

sqlquery

在 EF 6.4 的情况下,我需要使用类似的东西

  var parameters = new List<SqlParameter> parameters  // using System.Data.SqlClient
  sql = $"{sql} and ( headkey like @headkey)";
  parameters.Add(new SqlParameter("@headkey", $"%{headKey}%") { DbType = DbType.String });

答案 9 :(得分:-1)

我在使用

时遇到了同样的错误
cmd.Parameters.Add(pars)

其中parsSqlParameter的数组。问题是我使用的是Add()功能,但我应该使用AddRange()代替。

cmd.Parameters.AddRange(pars)