C# 参数';?用户电子邮件';在集合中找不到

C# 参数';?用户电子邮件';在集合中找不到,c#,mysql,asp.net,visual-studio,prepared-statement,C#,Mysql,Asp.net,Visual Studio,Prepared Statement,我正在使用MySql 5.6x和Visual Studio 2015,windows 10,64位。C作为编程语言。在我的CRUD.cs(类文件)中,我创建了以下方法: public bool dbQuery(string sql,string[] paramList= null) { bool flag = false; try { connect(); cmd = new MySqlCommand(sql,con); c

我正在使用MySql 5.6x和Visual Studio 2015,windows 10,64位。C作为编程语言。在我的CRUD.cs(类文件)中,我创建了以下方法:

public bool dbQuery(string sql,string[] paramList= null)
{
    bool flag = false;
    try
    {
        connect();
        cmd = new MySqlCommand(sql,con);
        cmd.Prepare();
        if(paramList != null){ 
         foreach(string i in paramList){
                string[] valus = i.Split(',');
                string p = valus[0];
                string v = valus[1];
                cmd.Parameters[p].Value = v;
            }
         }
        if (cmd.ExecuteNonQuery() > 0)
        {
            flag = true;
        }
    }
    catch (Exception exc)
    {
        error(exc);
    }
   }
我正在传递查询和参数列表,如下所示:

  protected void loginBtn_Click(object sender, EventArgs e)
  {
    string sql = "SELECT * FROM dept_login WHERE (user_email = ?user_email OR user_cell = ?user_cell) AND userkey = ?userkey";
    string[] param = new string[] {
         "?user_email,"+ userid.Text.ToString(),
         "?user_cell,"+ userid.Text.ToString(),
         "?userkey,"+ userkey.Text.ToString()
    };
    if (db.dbQuery(sql, param))
    {
        msg.Text = "Ok";
    }
    else
    {
        msg.Text = "<strong class='text-danger'>Authentication Failed</strong>";
    }
  }
我发送这样的参数是正确的吗?还有其他方法可以做到这一点吗? 谢谢


编辑:我认为最好的方法可能是使用二维数组来收集参数及其值,然后在方法中循环以获取cmd.AddWidthValues()中的参数?我可能错了…

在您的数据库查询中,您没有使用预期的名称创建参数集合,因此当您尝试为不存在的参数设置值时,会出现错误

public bool dbQuery(string sql,string[] paramList= null)
{
    bool flag = false;
    try
    {
        connect();
        cmd = new MySqlCommand(sql,con);
        cmd.Prepare();
        if(paramList != null){ 
            foreach(string i in paramList){
                string[] valus = i.Split(',');
                string p = valus[0];
                string v = valus[1];
                cmd.Parameters.AddWithValue(p, v);
            }
        }
        if (cmd.ExecuteNonQuery() > 0)
           flag = true;
    }
    catch (Exception exc)
    {
        error(exc);
    }
}
当然,这将添加每个数据类型等于字符串的参数,因此,如果数据表列不是字符串类型,则很容易出错

一个更好的方法是这个

List<MySqlParameter> parameters = new List<MySqlParameter>()
{
   {new MySqlParameter() 
        { 
           ParameterName = "?user_mail", 
           MySqlDbType= MySqlDbType.VarChar,
           Value = userid.Text
         },
   {new MySqlParameter() 
        { 
           ParameterName = "?user_cell", 
           MySqlDbType= MySqlDbType.VarChar,
           Value = userid.Text
         },

   {new MySqlParameter() 
        { 
           ParameterName = "?userkey", 
           MySqlDbType = MySqlDbType.VarChar,
           Value = userkey.Text
         },

}
if (db.dbQuery(sql, parameters))
 ....

当然,这意味着当您想要插入、更新或删除需要ExecuteOnQuery的记录时会遇到麻烦。创建一个通用函数来处理不同类型的查询非常困难,不值得进行所需的工作和调试。最好使用一些众所周知的ORM软件,如EntityFramework或Dapper。

您的SQL命令的参数集合不包含这些参数,因此您不能以这种方式对它们进行索引:
cmd.Parameters[p].Value=v

您需要以以下方式将它们添加到命令的参数集合:
cmd.Parameters.AddWithValue(p,v)

您知道
?user\u email
?user\u cell
都从
userid.Text.ToString()
获取值。是的,用户id可能是user\u email或user\u cell numberHmm,您是对的@史提夫。另外,我刚刚测试了您更改的cmd.Paremters.AddWithValue(p,v)行。我提供了正确的用户id和密码,但如果(cmd.ExectureNonQuery()>0)返回false,则仍然可以?您正在调用SELECT查询。ExecuteOnQuery用于插入、更新和删除,如果您想获取数据,需要使用ExecuteReader或通过DataAdapter填充数据表。非常感谢@Steve,我非常感谢您的方法。
List<MySqlParameter> parameters = new List<MySqlParameter>()
{
   {new MySqlParameter() 
        { 
           ParameterName = "?user_mail", 
           MySqlDbType= MySqlDbType.VarChar,
           Value = userid.Text
         },
   {new MySqlParameter() 
        { 
           ParameterName = "?user_cell", 
           MySqlDbType= MySqlDbType.VarChar,
           Value = userid.Text
         },

   {new MySqlParameter() 
        { 
           ParameterName = "?userkey", 
           MySqlDbType = MySqlDbType.VarChar,
           Value = userkey.Text
         },

}
if (db.dbQuery(sql, parameters))
 ....
public bool dbQuery(string sql, List<MySqlParameter> paramList= null)
{
    bool flag = false;
    try
    {
        connect();
        cmd = new MySqlCommand(sql,con);
        cmd.Prepare();
        if(paramList != null)
         cmd.Parameters.AddRange(paramList.ToArray());

        if (cmd.ExecuteNonQuery() > 0)
        {
            flag = true;
        }
    }
    catch (Exception exc)
    {
        error(exc);
    }
}
    using(MySqlDataReader reader = cmd.ExecuteReader())
    {
        flag = reader.HasRows;
    }