如何在C#中创建一个方法,允许我准备任何insert/update语句?
我正在尝试编写一个小类,它将帮助我使用C#和winforms连接到MySQL服务器。 我编写的连接将启动和关闭连接 我想在这里做的是在这个类中创建一个方法,允许我“在数组中”传递查询和值,该方法将自动为我准备查询 因此,不要像这样为每个插入/更新查询编写方法或代码如何在C#中创建一个方法,允许我准备任何insert/update语句?,c#,mysql,prepare,C#,Mysql,Prepare,我正在尝试编写一个小类,它将帮助我使用C#和winforms连接到MySQL服务器。 我编写的连接将启动和关闭连接 我想在这里做的是在这个类中创建一个方法,允许我“在数组中”传递查询和值,该方法将自动为我准备查询 因此,不要像这样为每个插入/更新查询编写方法或代码 MySqlCommand command = connection.CreateCommand(); command.CommandText = "INSERT INTO mytable(a,b,c,d)VALUES
MySqlCommand command = connection.CreateCommand();
command.CommandText = "INSERT INTO mytable(a,b,c,d)VALUES (?, ?, ?, ?)";
command.Parameters.AddWithValue("?", array_val1);
command.Parameters.AddWithValue("?", array_val2);
command.Parameters.AddWithValue("?", array_val3);
command.Parameters.AddWithValue("?", array_val4);
connection.Open();
command.ExecuteNonQuery();
我希望有一个方法,我可以传递查询和值,它会自动为我准备语句
像这样的
//Call the Method
processQuery("INSERT INTO mytable(a,b,c,d)VALUES (?, ?, ?, ?)", array(1,2,3,4));
//The new Method
public processQuery(string sqlStr, array values){
MySqlCommand command = connection.CreateCommand();
command.CommandText = sqlStr;
command.Parameters.AddWithValue("?", array_val1);
command.Parameters.AddWithValue("?", array_val2);
command.Parameters.AddWithValue("?", array_val3);
....
....
....
....
command.Parameters.AddWithValue("?", array_val_SIZE_OF_ARRAY);
connection.Open();
command.ExecuteNonQuery();
}
您可以让您的方法接受一个表名和一个MySqlParameter列表,然后根据您传入的内容构建SQL
public void ProcessQuery(string tableName, MySqlParameter keyParam, params MySqlParameter[] sqlParams)
{
using(MySqlConnection cn = new MySqlConnection(this.ConnectionString))
using(MySqlCommand cmd = cn.CreateCommand())
{
/*Update Statement*/
//Param1 = @Param1, Param2 = @Param2, @Param3 = @Param3, etc.
string updateParamStr = string.Join(
", ",
sqlParams.Select(sqlParam => string.Format("{0} = {1}", sqlParam.ParameterName.Substring(1), sqlParam.ParameterName)));
//param = @param
string keyMatchStr = string.Format("{0} = {1}",
keyParam.ParameterName.Substring(1),
keyParam.ParameterName);
string updateSql = string.Format("UPDATE {0} SET {1} WHERE {2}",
tableName,
updateParamStr,
keyMatchStr);
/*Insert Statement*/
//produce comma delimited list of param names with leading @ stripped eg. Param1, Param2, Param3
string columnNameStr = string.Join(", ", sqlParams.Select(sqlParam => sqlParam.ParameterName.Substring(1)));
//produce comma delimited list of param eg. @Param1, @Param2, @Param3
string valueParamStr = string.Join(", ", sqlParams.Select(sqlParam => sqlParam.ParameterName));
string insertSql = string.Format("INSERT INTO {0} ({1}) VALUES ({2})",
tableName,
columnNameStr,
valueParamStr);
/*Combined Update and Insert*/
string combinedSql = string.Format("{0} {1} WHERE ROW_COUNT() = 0", updateSql, insertSql);
cmd.CommandText = combinedSql;
cmd.Parameters.Add(keyParam);
cmd.Parameters.AddRange(sqlParams);
cn.Open();
cmd.ExecuteNonQuery();
}
}
生成的SQL将创建一个组合的UPDATE和INSERT语句,如下所示:
UPDATE MyTable SET Col1 = @Col1, Col2 = @Col2 WHERE KeyCol = @KeyCol
INSERT INTO MyTable (Col1, Col2) VALUES (@Col1, @Col2) WHERE ROW_COUNT() = 0
这将有效地运行更新,该更新要么更新匹配的行,要么什么也不更改。在后一种情况下,ROW_COUNT()将=0,这将使INSERT语句完成其工作。我们只是利用每条语句中的WHERE子句使事情相互排斥
然后调用传递唯一键的MySqlParameter的方法,然后调用任意多的MySqlParameter对象
ProcessQuery(
"MyTable",
new MySqlParameter("@MyKeyColumn", 5)/*unique key column*/,
new MySqlParameter("@SomeColumn", 1),
new MySqlParameter("@SomeOtherColumn", "Some string"));
这样做的好处是,如果您愿意,可以在MySqlParameter中提供数据类型信息,也可以使用名称+值对使其保持简单。这确实需要使用@ParamName语法而不是“?”,并且参数名称与目标列相匹配,这在我看来更清楚。不知道为什么会被否决或标记为关闭。这是一个有明确目标的恰当问题。你的代码是否因为某种原因而不起作用?你能提供更多关于什么不起作用的上下文吗?你认为不同数据类型的列会成为一个问题吗?@JoshSmeaton,我希望你在他们投票否决之前留下一个便条!无论如何,目的是使代码动态化,这样我就不必每次都写代码了。忘掉这些,使用实体框架。现在已经不是90年代了。这对插入有好处。但我如何使用它来运行更新…集?或插入。。。。。重复更新?ThanksHow您希望将新记录与现有记录区分开来吗?您是在传递某种类型的键或标识字段+值,还是在考虑其他机制?对于更新,我应该能够传递任何插入/更新,它应该只处理它。因此,在更新中,我将使用where is=变量。对于插入到。。。。在复制键上,这是一个mysql的东西。我可以识别一个唯一的列,如果找到唯一的键,mysql将进行插入或更新