AddWithValue方法(C#)什么都不做

时间:2009-01-13 22:01:11

标签: c# sql ado.net

我正在编写一个类来处理我的应用程序中的所有数据库活动,所以我来到执行UPDATE查询的方法。

截至目前,我正在返回并显示commandtext的内容以进行检查,看起来很好:

UPDATE news SET title = @title, newsContent = @newsContent, excerpt = @excerpt, date = @date, urlTitle = @urlTitle, isPublished = @isPublished WHERE (id = @id);

所以,换句话说,很好。下一步是用实际值替换所有@values - 这就是我遇到问题的地方。什么都没发生。 AddWithValue方法似乎没有做任何事情,我没有理由这样做。

public string updateQuery(string table, string[] fields, object[] values, string conditionField, object conditionValue)
{
    try
    {
        StringBuilder cmd = new StringBuilder("UPDATE " + table + " SET ");

        int i = 1;
        foreach (string s in fields)
        {
            if (i == fields.Length)
            {
                cmd.Append(s + " = @" + s + " ");
            }
            else
            {
                cmd.Append(s + " = @" + s + ", ");
            }

            i++;
        }

        cmd.Append("WHERE (" + conditionField + " = @" + conditionField + ");");
        command.CommandText = cmd.ToString();

        int j = 0;
        foreach (object o in values)
        {
            command.Parameters.AddWithValue("@" + fields[j], o);
            j++;
        }
        command.Parameters.AddWithValue("@" + conditionField, conditionValue);

        command.ExecuteNonQuery();
        connection.Close();

        return command.CommandText;
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

任何?

7 个答案:

答案 0 :(得分:2)

“你什么都不做”是什么意思?你是说在执行命令时参数没有值?或者命令文本保持不变?

如果是后者那么这是预期的。该命令不会更改查询文本,它会将查询文本与参数值一起发送到服务器。

答案 1 :(得分:2)

感谢Joel Coehoorn的建议,我会调查他们。

不过,我想让我的东西上班:p

注意到日期字段实际上一直在更新自己。但是,没有其他领域。这看起来越不正确。也许在早上尝试比在午夜更好。

编辑: 找出问题所在,这比我预期的要简单得多。我忘了检查页面是否是回发,因此每次更新数据库时,在调用submit-method之前,字段都填充了数据库中的数据。因此,更新方法始终如一。 腮红

答案 2 :(得分:1)

arg值是否可能为空?如果是这样,则不会添加参数。对于null,您需要使用DBNull.Value;例如(不是唯一的方法):

cmd.Parameters.AddWithValue(argName, (object)argValue ?? DBNull.Value);

答案 3 :(得分:1)

您提供的ID的值可能与您要更新的表中的条目不匹配。

BTW放弃了try ..catch它没有任何用途。

答案 4 :(得分:1)

如果您希望更新字符串,您会感到失望。使用参数化查询的一个重要特性是,值永远不会直接替换为命令字符串,因此您可以免受此类安全漏洞的影响。相反,数据会单独传输到服务器。

让我建议这个新功能签名:

public string updateQuery(string table, IEnumerable<KeyValuePair<string, object>> values, KeyValuePair<string, object> condition)

这将在您的参数名称和值之间建立强关联,并且还可以灵活地使用除数组之外的构造(尽管也可以接受数组)。然后代码看起来像这样:

public string updateQuery(string table, IEnumerable<KeyValuePair<string, object>> values, KeyValuePair<string, object> condition)
{
    using (StringBuilder cmd = new StringBuilder("UPDATE [" + table + "]\nSET "))
    {
        string delimiter = "";
        foreach (KeyValuePair<string, object> item in values)
        {
           cmd.AppendFormat("{0}[{1}]=@{1}", delimiter, item.Key);
           delimiter = ",\n";
        }
        cmd.AppendFormat("\nWHERE [{0}]= @{0};", condition.Key);

        command.CommandText = cmd.ToString();
    }

    foreach (KeyValuePair<string, object> item in values)
    {
        command.Parameters.AddWithValue("@" + item.Key, (object)item.Value ?? DBNull.Value);
    }
    command.Parameters.AddWithValue("@" + condition.Key, condition.Value);

    // you didn't show where the connection was created or opened
    command.ExecuteNonQuery();    
    connection.Close();

    return command.CommandText;
}

如果您可以使用能够创建强类型数据库参数的东西(例如IEnumerable<SqlParameter>),那就更好了。

答案 5 :(得分:0)

我猜我还会发布其余的代码。首先传递值的方法:

public void updatePost(int postId)
{
    DbConnection d = new DbConnection();

    string[] fields = {
                          "title",
                          "newsContent",
                          "excerpt",
                          "date",
                          "urlTitle",
                          "isPublished" 
                      };

    object[] values = {
                          this.title,
                          this.content,
                          this.excerpt,
                          this.date,
                          this.urlTitle,
                          this.isPublished,
                      };

    d.updateQuery("news",fields,values,"id",postId);
}

连接到数据库的构造方法:

public DbConnection()
{        
    connection = new SqlConnection("Data Source=****; User Id=****; Password=*****;");
    connection.Open();
    command = connection.CreateCommand();
}

我还没有找到问题所在,但我真的非常感谢所有帮助。 : - )

答案 6 :(得分:0)

使用我的其他代码,您的新updatePost方法将如下所示。

using DBParam = KeyValuePair<string, object>; // reduce need to keep re-typing this

public void updatePost(int postId)
{   
    List<DBParam> values = new List<DBParam>();

    values.Add(new DBParam("title", this.title));
    values.Add(new DBParam("newsContent", this.content));
    values.Add(new DBParam("excerpt", this.excerpt));
    values.Add(new DBParam("date", this.date));
    values.Add(new DBParam("urlTitle", this.urlTitle));
    values.Add(new DBParam("isPublished", this.isPublished));

    new DbConnection().updateQuery("news", values, new DBParam("id", postid));
}