【问题标题】:"SqlParameterCollection only accepts non-null SqlParameter type objects, not String objects"“SqlParameterCollection 只接受非空的 SqlParameter 类型对象,不接受 String 对象”
【发布时间】:2014-03-28 06:32:04
【问题描述】:

我不断收到异常

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();
        }
    }
}

请告诉我哪里出错了。

【问题讨论】:

标签: c# .net sql-server database


【解决方案1】:

我尝试了上述所有步骤,但没有任何帮助。

通过更改命名空间终于找到并修复了

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

阿尔沙德

【讨论】:

  • 太棒了。你节省了我的时间
  • 我认为 System.Data.SqlClient 是retired
  • 也解决了我的问题。
  • 第二次为我解决了这个问题。谢谢!
  • 谢谢!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!我生命中的 3 小时 haha​​aaaaaaa
【解决方案2】:

我用 Microsoft.Data.SqlClient 替换了对 System.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;
        }
    }

【讨论】:

  • 老实说,我认为 Visual Studio 有问题,但后来我尝试将一个转换为另一个。
【解决方案3】:

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

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

【讨论】:

  • 我认为这是迄今为止最简单最简单的方法
  • 但是AddWithValue会为SQL Server生成不同长度的参数,并创建不同的执行计划。最好添加参数并指定长度(例如:搜索@name='Alex' 或搜索@name='Martin' 将为Alex 生成VARCHAR(4) 为Martin 生成VARCHAR(6) 和不同的参数) SQL Server 中的执行计划)
  • Microsoft.Data.SqlClient.SqlParameterCollection 不再有 AddWithValue
  • 不要使用 AddWithValue link
【解决方案4】:

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

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

到这里:

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

其他参数也一样。

【讨论】:

    【解决方案5】:

    试试下面

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

    【讨论】:

      【解决方案6】:

      我遇到了同样的问题,但我正在做一个 object[2] = object[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;
              }
          }
      

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

      【讨论】:

        【解决方案7】:

        对于此问题的任何未来读者 - 示例处理 .Add(),但如果使用不正确,.Remove() 也会抛出此错误。正如其他人所记录的那样,使用.Add() 的正确方法是:

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

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

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

        【讨论】:

          【解决方案8】:

          我在使用时遇到了同样的错误

          cmd.Parameters.Add(pars)
          

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

          cmd.Parameters.AddRange(pars)
          

          【讨论】:

            【解决方案9】:

            以下简单的解决方案适合我:

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

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

            【讨论】:

              【解决方案10】:

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

              在 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 });
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2012-11-19
                • 2011-03-18
                • 1970-01-01
                • 1970-01-01
                • 2022-01-22
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多