使用C#查询MySQL更有效的方法是什么?
基于StackOverflow站点的链接(参考资料如下),我提出了这段代码,用于执行从C#应用程序到MySQL数据库的查询使用C#查询MySQL更有效的方法是什么?,c#,mysql,datareader,mysqldatareader,C#,Mysql,Datareader,Mysqldatareader,基于StackOverflow站点的链接(参考资料如下),我提出了这段代码,用于执行从C#应用程序到MySQL数据库的查询 using (var dbConn = new MySqlConnection(config.DatabaseConnection)) { using (var cmd = dbConn.CreateCommand()) { dbConn.Open(); cmd.CommandType = CommandType.Text;
using (var dbConn = new MySqlConnection(config.DatabaseConnection))
{
using (var cmd = dbConn.CreateCommand())
{
dbConn.Open();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT version() as Version";
using (IDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
Console.WriteLine("Database Version: " + reader.GetString(reader.GetOrdinal("Version")));
}
}
}
}
我遇到的问题是,每次我有一组查询要做时,我都必须构建大量的代码块,因为在应用程序的生命周期中,我不(也不应该)保持连接打开
是否有更有效的方法来构建支持结构(使用s嵌套的、打开连接等),并传递我的连接字符串和我想要运行的查询并返回结果
参考问题:
- -特别是答案
特塞尔
这是我看过的三个。还有一些,但我的Google fu现在无法重新查找。所有这些都为如何执行单个查询提供了答案。我希望执行单独的业务逻辑查询(其中一些是重复的),并且不希望重复不需要的代码
我所尝试的:
根据nawfal的评论,我有以下两种方法:
private MySqlDataReader RunSqlQuery(string query)
{
Dictionary<string, string> queryParms = new Dictionary<string, string>();
MySqlDataReader QueryResult = RunSqlQuery(query, queryParms);
return QueryResult;
}
private MySqlDataReader RunSqlQuery(string query, Dictionary<string, string> queryParms)
{
MySqlDataReader reader = null;
if (queryParms.Count > 0)
{
// Assign parameters
}
try
{
using (var dbConn = new MySqlConnection(config.DatabaseConnection))
{
using (var cmd = dbConn.CreateCommand())
{
dbConn.Open();
cmd.CommandType = CommandType.Text;
cmd.CommandText = query;
using (reader = cmd.ExecuteReader())
{
return reader;
}
}
}
}
catch (MySqlException ex)
{
// Oops.
}
return reader;
}
private MySqlDataReader RunSqlQuery(字符串查询)
{
Dictionary queryParms=新字典();
MySqlDataReader QueryResult=RunSqlQuery(query,queryParms);
返回查询结果;
}
私有MySqlDataReader RunSqlQuery(字符串查询、字典查询)
{
MySqlDataReader=null;
如果(queryparts.Count>0)
{
//指定参数
}
尝试
{
使用(var dbConn=newmysqlconnection(config.DatabaseConnection))
{
使用(var cmd=dbConn.CreateCommand())
{
dbConn.Open();
cmd.CommandType=CommandType.Text;
cmd.CommandText=查询;
使用(reader=cmd.ExecuteReader())
{
返回读取器;
}
}
}
}
捕获(MySqlException-ex)
{
//哎呀。
}
返回读取器;
}
这种尝试的问题是读取器从方法返回时关闭 您是否考虑过使用?我喜欢你和我自己,但有很多。而且也是流行的微软解决方案
有了这些工具,您的查询就变成了非常简单的CRUD方法调用,可以(主要)为您进行连接和会话处理。为什么要从该方法返回datareader?使用
块将其包裹在内后,它将关闭。另外,您只能在获得IDbCommand
的实例后才能分配参数,因此我已使用块将该部分移动到的内部
如果您严格希望返回datareader,那么最好使用yield
关键字返回IEnumerable
private IEnumerable<IDataRecord> RunSqlQuery(string query,
Dictionary<string, string> queryParms)
{
using (var dbConn = new MySqlConnection(config.DatabaseConnection))
{
using (var cmd = dbConn.CreateCommand())
{
if (queryParms.Count > 0)
{
// Assign parameters
}
cmd.CommandText = query;
cmd.Connection.Open();
using (var reader = cmd.ExecuteReader())
foreach (IDataRecord record in reader as IEnumerable)
yield return record;
}
}
}
private IEnumerable RunSqlQuery(字符串查询,
字典(查询武器)
{
使用(var dbConn=newmysqlconnection(config.DatabaseConnection))
{
使用(var cmd=dbConn.CreateCommand())
{
如果(queryparts.Count>0)
{
//指定参数
}
cmd.CommandText=查询;
cmd.Connection.Open();
使用(var reader=cmd.ExecuteReader())
foreach(读卡器中的IDataRecord记录为IEnumerable)
收益回报记录;
}
}
}
或者更好的方法是读取数据并返回数据。这样,您就不必依赖db类之外的db名称空间中的类 我一直在走那条路。按照建议ORMs的思路,我首先推荐EF代码。很抱歉,有点离题了,但在第一次使用EF代码之后,我从未想过要回到这个模式
在代码优先之前,EF是一个相当痛苦的问题,但现在它已经成熟,如果你有一个DB,你就有可能修改结构,即一个新的应用程序功能需要一个新的表或列,那么EF代码优先的方法是我的建议。如果是第三方数据库或其他应用程序的数据库,由其他人管理其结构,那么您只需要在他们部署更改时刷新数据模型,那么我不会首先使用代码,而只使用传统的EF,您可以根据一些现有数据库生成/更新模型
using (var dbConn = new MySqlConnection(config.DatabaseConnection))
{
using (var cmd = dbConn.CreateCommand())
{
dbConn.Open();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT version() as Version";
using (IDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
Console.WriteLine("Database Version: " + reader.GetString(reader.GetOrdinal("Version")));
}
}
}
}
注意,您可以采用EF并开始使用它,同时保持现有的代码基础不变。这取决于您的框架在多大程度上依赖于使用ADO对象。EF电动工具扩展有一种生成代码优先模型的方法,或者您可以使用传统的非代码优先EF从数据库生成模式
using (var dbConn = new MySqlConnection(config.DatabaseConnection))
{
using (var cmd = dbConn.CreateCommand())
{
dbConn.Open();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT version() as Version";
using (IDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
Console.WriteLine("Database Version: " + reader.GetString(reader.GetOrdinal("Version")));
}
}
}
}
当您想要查询时,您可以直接进入您想要查询的业务,而无需大量的基础结构代码或包装。关于上述包装器的另一件事是,在一些边缘情况下,您必须重新使用ADOAPI而不是RunSqlQuery助手
这是一个很小的例子,因为通常我没有像GetActivePeopleNames这样的方法,只是将查询放在需要的地方。在松散的代码方面几乎没有开销,因此在所有其他代码中使用我的查询不会显得太突兀。虽然我确实练习了一些presenter模式,以从业务逻辑中抽象查询和数据转换
HREntities db = new HREntities();
private ICollection<string> GetActivePeopleNames()
{
return db.People.Where(p => p.IsActive).Select(p => p.FirstName + " " + p.LastName)
.ToList();
}
HREntities db=新的HREntities();
私有ICollection GetActivePeopleNames()
{
返回db.People.Where(p=>p.IsActive)。选择(p=>p.FirstName+“”+p.LastName)
.ToList();
}
我不必创建参数对象。我本可以为使用一些变量,其中(p=>p.IsActive==someBool)
,在这种情况下,SQL注入是安全的。连接是自动处理的。我可以使用.Include在同一个c语言中获取相关对象
RunSqlQuery("SELECT * FROM ...", reader => ReadResult(reader));
private bool ReadResult(MySqlDataReader reader)
{
//Use the reader to read the result
if (!success)
return false;
return true;
}
private bool RunSqlQuery(string query, Func<MySqlDataReader, bool> readerAction)
{
Dictionary<string, string> queryParms = new Dictionary<string, string>();
return RunSqlQuery(query, readerAction, queryParms);
}
private bool RunSqlQuery(string query, Func<MySqlDataReader, bool> readerAction, Dictionary<string, string> queryParms)
{
MySqlDataReader reader = null;
if (queryParms.Count > 0)
{
// Assign parameters
}
try
{
using (var dbConn = new MySqlConnection(config.DatabaseConnection))
{
using (var cmd = dbConn.CreateCommand())
{
dbConn.Open();
cmd.CommandType = CommandType.Text;
cmd.CommandText = query;
using (reader = cmd.ExecuteReader())
{
return readerAction.Invoke(reader);
}
}
}
}
catch (MySqlException ex)
{
// Oops.
return false;
}
}