C#和MySQL-返回DataReader(或其内容)的方法
本文关键字:方法 MySQL- 返回 DataReader | 更新日期: 2023-09-27 18:20:50
在整个程序中,我将重复使用(MySQL的)SELECT命令。每一次,我都必须建立联系和东西。我正在考虑制作一个方法,接收SELECT命令字符串并返回参数的等效DataReader。我想这将帮助我减少每次必须生成的大量代码。
我想以这样的方式使用它:
MySqlDataReader myReader = myObj.loadDataToReader("SELECT * FROM tblSample");
然后,我可以像普通的MySqlDataReader一样操作myReader
。然而,我担心的是,在使用数据读取器时,连接必须是打开的,当然,它的相关内容(读取器和连接)需要关闭等等(我认为这是一种传统的安全措施)。我一直在看互联网上的东西,似乎找不到如何做到这一点的提示。
我正在尝试,我有以下代码行:
public MySqlDataReader loadDataToReader(string selectCommand)
{
MySqlDataReader myReader = null;
string myConnectionString = "Data Source = " + server + "; User = " + user + "; Port = 3306; Password = " + password + ";";
string useDataBaseCommand = "USE " + dbName + ";";
using (MySqlConnection myConnection = new MySqlConnection(myConnectionString))
{
using (MySqlCommand myCommand = new MySqlCommand(useDataBaseCommand + selectCommand, myConnection))
{
try
{
myConnection.Open();
myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection);
}
catch (Exception ex)
{
myConnection.Close();
MessageBox.Show(ex.Message, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return myReader;
}
}
}
在另一个类的方法中,我创建了一个对象,以便能够使用上面定义的方法,其方式如下:
string selectTableCommand = "SELECT * FROM tblusers WHERE Username = ''" + txtID.Text + "'' AND Password = ''" + txtPassword.Text + "'';";
MySQLOperations objSQLOperations = new MySQLOperations("localhost", "root", "mypass", "mydatabase");
MySqlDataReader myDataReader = objSQLOperations.loadDataToReader(selectTableCommand);
if (myDataReader.Read() && txtPassword.Text.Equals(myDataReader["Password"].ToString()))
{ /* do something */ }
else
{ /* do something */ }
然而,我收到一条消息说:"当阅读器关闭时,尝试阅读无效!"我该如何纠正并使其发挥作用?或者更确切地说,有没有更合适的方法来做到这一点?我该如何确保我的连接/阅读器在使用后关闭?
您可以使方法通用,并注入一个函数来处理读取器,然后返回函数的输出,而不是读取器:
public T LoadDataToReader<T>(string selectCommand, Func<IDataReader,T> ProcessResults)
{
string myConnectionString = "Data Source = " + server + "; User = " + user + "; Port = 3306; Password = " + password + ";";
string useDataBaseCommand = "USE " + dbName + ";";
using (var myConnection = new MySqlConnection(myConnectionString))
{
myConnection.Open();
using (var myCommand = myConnection.CreateCommand())
{
myCommand.CommandText = useDataBaseCommand + selectCommand;
using(var myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection))
{
return ProcessResults(myReader);
}
}
}
}
我还做了一些其他更改:
IDataReader
实现了IDisposable
,所以我为阅读器添加了using语句- 我使用ADO.NET接口方法来创建命令,而不是构造函数
- 我删除了catch块,因为当您离开using块时,连接会自动关闭,并且UI代码(例如
MessageBox
)不属于DAL代码。相反,这应该作为对该方法的调用的try/catch来完成 - 我将函数的第一个字母大写,以使其符合.NET编码标准
然后,您只需按如下方式使用它:
public static string GetStringData(IDataReader reader)
{
var ord_name = reader.GetOrdinal("Name");
if(reader.Read())
return reader.GetString(ord_name);
return null;
}
public static IEnumerable<Foo> GetFoos(IDataReader reader)
{
var ord_name = reader.GetOrdinal("Name");
var foos = new List<Foo>();
while(reader.Read())
foos.Add(new Foo {Name = reader.GetString(ord_name)});
return foos;
}
static void Main(string[] args)
{
var program = new Program();
try
{
var name = program.LoadDataToReader("SELECT name FROM thename", GetStringData);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
try
{
var foos = program.LoadDataToReader("SELECT foos FROM footable", GetFoos);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
此外,您可能应该传入连接字符串,而不是从字段构建它。或者,您可以为整个连接字符串设置一个字段(只构建一次,而不是每次执行)并使用它。
此外,数据库可以用Initial Catalog
或Database
设置在连接字符串中,这比用USE database
子句作为select语句的前缀更可取。