try
{
string connString = "server=db4free.net;port=3306;database=secretdb;user id=secret;password=secret;charset=utf8";
MySqlConnection conn = new MySqlConnection(connString);
conn.Open();
MySqlCommand cmd = new MySqlCommand("SELECT School_Name FROM schools WHERE School_ID=@id", conn);
cmd.Parameters.AddWithValue("@id", "1");
var schoolName = cmd.ExecuteScalar();
label1.Text = schoolName.ToString();
conn.close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
上面的代码返回异常抛出异常:' System.Collections.Generic.KeyNotFoundException'在mscorlib.dll中
但是每当我使用诸如 INSERT,UPDATE和DELETE之类的查询时,它都能正常工作。就像下面的代码一样:
try
{
string connString = "server=db4free.net;port=3306;database=secretdb;user id=secret;password=secret;charset=utf8";
MySqlConnection conn = new MySqlConnection(connString);
conn.Open();
MySqlCommand cmd = new MySqlCommand("INSERT INTO schools(School_Name,School_Address) VALUES(@name,@address)", conn);
cmd.Parameters.AddWithValue("@name", "Sample Name");
cmd.Parameters.AddWithValue("@address", "Sample Address");
cmd.ExecuteNonQuery();
label1.Text = "Success";
conn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
基本上我的问题如下:
答案 0 :(得分:1)
首先,您的代码可以在发生异常时保持连接打开。 conn.Close()
应移至finally
块。
其次,要查询值,您应该使用cmd.ExecuteReader()
方法,该方法将返回MySqlDataReader
个对象;要处理它,您可以使用using()
构造。 ExecuteScalar()
方法用于插入/更新/删除语句,并返回受影响的行数。
第三,但同样重要:考虑将与数据库相关的代码移动到Repository类,然后从Form逻辑中调用存储库类代码。这样您就可以获得可重复使用的代码。 存储库类的起点的简单示例:
public class Repository
{
public string ConnectionString { get; private set; }
public Repository(string connectionString)
{
this.ConnectionString = connectionString;
}
public string GetSchoolNameById(int id)
{
string schoolName = null;
MySqlConnection conn = null;
try
{
conn = new MySqlConnection(this.ConnectionString);
conn.Open();
using (MySqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT School_Name FROM schools WHERE School_ID=@id";
cmd.Parameters.AddWithValue("@id", id);
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
if (!rdr.IsDBNull(rdr.GetOrdinal("School_Name")))
{
schoolName = rdr.GetString(rdr.GetOrdinal("School_Name"));
}
}
}
}
}
catch (Exception ex)
{
// maybe log exception here, or rethrow it if you want
// the consumer to manage it. This depends on how you plan to build your software architecture.
}
finally
{
// this code will run always, either if everything ran correctly or if some exception occurred in the try block.
if (conn != null)
{
conn.Close();
conn.Dispose();
}
}
return schoolName;
}
}
然后,您的表单代码可以简单如下:
Repository rep = new Repository("server=db4free.net;port=3306;database=secretdb;user id=secret;password=secret;charset=utf8");
try
{
// the try/catch is necessary if you have decided to re-throw the exception in the Repository.GetSchoolNameById method
label1.Text = rep.GetSchoolNameById(1);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}