【发布时间】:2021-02-13 18:30:19
【问题描述】:
我一直在尝试编写连接代码来连接数据库。进展顺利,但我遇到了一个我似乎无法解决的奇怪问题。
当我尝试向查询中添加参数时,它不会检索数据。但是当我切换出参数时,它确实会检索到正确的数据。
数据访问层如下所示。 (我知道这很不安全,但我才刚刚开始):
public static class UserDA
{
private static MySqlCommand cmd = null;
private static DataTable dt;
private static MySqlDataAdapter da;
public static User RetrieveUser(String username)
{
// Create the query
const String query = "SELECT `Username`, `Password` FROM login WHERE `Username` = '@Username';";
cmd = DbHelper.Select(
query,
new Dictionary<String, String>
{
{"@Username", username}
});
//Setup model
User user = null;
if (cmd == null) return null;
// Get the data and add it to the user model
dt = new DataTable();
da = new MySqlDataAdapter(cmd);
da.Fill(dt);
foreach (DataRow dataRow in dt.Rows)
{
user = new Models.User(
dataRow["Username"].ToString(),
dataRow["Password"].ToString());
}
return user;
}
}
Select 方法如下所示:
public static class DbHelper
{
private static MySqlConnection _connection;
private static MySqlCommand _cmd;
private static DataTable _dataTable;
private static MySqlDataAdapter _adapter;
public static void EstablishConnection()
{
// Gets a connection to the database. Code works.
}
/// <summary>
/// Give the query and a dict with the param name and value
/// </summary>
public static MySqlCommand Select(String query, Dictionary<String , String> param)
{
try
{
if (_connection != null)
{
_connection.Open();
_cmd = _connection.CreateCommand();
_cmd.CommandType = CommandType.Text;
_cmd.CommandText = query;
foreach (KeyValuePair<String, String> keyValuePair in param)
{
_cmd.Parameters.AddWithValue(keyValuePair.Key, keyValuePair.Value);
}
_cmd.ExecuteScalar();
_connection.Close();
}
}
catch (Exception e)
{
_connection?.Close();
}
return _cmd;
}
}
最后是用户模型:
public class User
{
public String Username;
public String Password;
public User(String username = "", String password = "")
{
Username = username;
Password = password;
}
}
当我尝试从中获取数据时会出现问题。如果我使用带有参数的选择查询,它不起作用,但只要我将参数更改为实际值,它就会很好地检索它。在这一点上,我真的很挠头。我是不是在某个地方忘记了一步?
谢谢!
【问题讨论】:
-
private static MySqlConnection _connection;是一个等待发生的错误。您可能不会跨线程共享 MySqlConnection 对象:mysqlconnector.net/troubleshooting/connection-reuse 相反,它们的创建成本非常低(由于连接池),因此只需在需要时创建一个新对象。还可以使用using语句(using (var connection = new MySqlConnection(connectionString)) { ... },您可以删除对Close(和异常处理程序)的显式调用;它将自动关闭。 -
最后,像stackexchange.github.io/Dapper 这样的库已经为您编写了所有这些代码;我强烈建议使用现成的解决方案,而不是尝试自己编写。
-
我一定要看看图书馆。不过我还是想先自己做一个,因为它是我 atm 的学习工具。我第一次真正用 C# 编写连接器。之前只在php中做过。
-
是的,自己编写代码是了解 ADO.NET 工作原理以及了解 Dapper 在后台做什么的绝佳方式。
标签: c# mysql mysql.data