有没有一种正确的方法可以打破foreach,以便IEnumerable <>知道我已经完成并且应该清理它.
请考虑以下代码:
private static IEnumerable<Person> getPeople()
{
using (SqlConnection sqlConnection = new SqlConnection("..."))
{
try
{
sqlConnection.Open();
using (SqlCommand sqlCommand = new SqlCommand("select id, firstName, lastName from people", sqlConnection))
{
using (SqlDataReader reader = sqlCommand.ExecuteReader())
{
while (reader.Read())
yield return new Person(reader.GetGuid(0), reader.GetString(1), reader.GetString(2));
}
}
}
finally
{
Console.WriteLine("finally disposing of the connection");
if (sqlConnection.State == System.Data.ConnectionState.Open)
sqlConnection.Close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果他的消费者没有脱离foreach,那么everthing很好并且读者将返回false,while循环willend并且该函数清除数据库命令和连接.但是如果在我结束之前呼叫者从foreach断开会发生什么呢?
连接已添加到连接池中.所以我关闭它,但它仍然保持身体开放.使用ConnectionString参数"Pooling = false"或静态方法MySqlConnection.ClearPool(连接)和MySqlConnection.ClearAllPools可以避免问题.请注意,问题是,当我关闭应用程序时,连接仍然存在.即使我关闭它.所以我要么根本不使用连接池,要么在关闭连接之前清除特定池,问题就解决了.我会花时间弄清楚在我的情况下什么是最好的解决方案.
感谢所有回答的人!它帮助我更好地理解了C#的概念,并从有用的输入中学到了很多东西.:)
===
我已经搜索了一段时间,并没有找到我的问题的解决方案:我是C#的新手并尝试编写一个类来使MySql Connections更容易.我的问题是,在我打开连接并关闭它之后.它仍然在数据库中打开并被中止.
我当然使用'using'语句,但是在退出程序后连接仍然是打开的并且被中止.
这是我的代码的样子:
using (DatabaseManager db = new DatabaseManager())
{
using (MySqlDataReader result = db.DataReader("SELECT * FROM module WHERE Active=1 ORDER BY Sequence ASC"))
{
foreach (MySqlDataReader result in db.DataReader("SELECT * FROM module WHERE Active=1 ORDER BY Sequence ASC"))
{
//Do stuff here
}
}
}
Run Code Online (Sandbox Code Playgroud)
类数据库管理器打开连接并在处理时关闭它:
public DatabaseManager()
{
this.connectionString = new MySqlConnectionStringBuilder("Server=localhost;Database=businessplan;Uid=root;");
connect();
}
private bool connect()
{
bool returnValue = true;
connection = new MySqlConnection(connectionString.GetConnectionString(false));
connection.Open();
}
public void …Run Code Online (Sandbox Code Playgroud) 下面是一个示例代码,用于使用我在google搜索时在几个地方找到的yield关键字从数据库中检索数据:
public IEnumerable<object> ExecuteSelect(string commandText)
{
using (IDbConnection connection = CreateConnection())
{
using (IDbCommand cmd = CreateCommand(commandText, connection))
{
connection.Open();
using (IDbDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
{
yield return reader["SomeField"];
}
}
connection.Close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我是否认为在此示例代码中,如果我们不遍历整个datareader,连接将不会被关闭?
如果我理解正确的收益,这是一个不会关闭连接的例子.
foreach(object obj in ExecuteSelect(commandText))
{
break;
}
Run Code Online (Sandbox Code Playgroud)
对于可能不是灾难性的数据库连接,我想GC最终会将其清理干净,但是如果不是连接它会是一个更关键的资源呢?
哪个会更快.
1)循环datareader并基于填充的数据表创建自定义行和列
2)或者创建一个dataAdapter对象并且只是(填充)一个数据表.
在动态创建数据表时,数据加载器的性能是否仍然适用?
最近我发现自己编写数据访问层选择方法,其中代码都采用这种通用形式:
public static DataTable GetSomeData( ... arguments)
{
string sql = " ... sql string here: often it's just a stored procedure name ... ";
DataTable result = new DataTable();
// GetOpenConnection() is a private method in the class:
// it manages the connection string and returns an open and ready connection
using (SqlConnection cn = GetOpenConnection())
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
// could be any number of parameters, each with a different type
cmd.Parameters.Add("@Param1", SqlDbType.VarChar, 50).Value …Run Code Online (Sandbox Code Playgroud) 基于StackOverflow站点周围的链接(下面的参考资料),我提出了这个代码块来执行从我的C#应用程序到MySQL数据库的查询.
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")));
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,每次我要进行一组查询时,我必须构建这个庞大的代码块,因为我不会(也不应该)在应用程序的生命周期中保持连接打开.
是否有更有效的方法来构建支持结构(嵌套usings,打开连接等),而是传递我的连接字符串和我想要运行的查询并获得结果?
参考问题:
这是我看过的三个.还有一些,但我的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 …Run Code Online (Sandbox Code Playgroud) 好的,我的代码目前是:
public MySqlDataReader CreateQuery(string queryString, string connectionString )
{
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
using (MySqlCommand command = new MySqlCommand(queryString, connection))
{
command.Connection.Open();
command.ExecuteNonQuery();
MySqlDataReader reader = command.ExecuteReader();
return reader;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在另一个函数中,我有:
using(MySqlDataReader readers = _connection.CreateQuery(query, connectString))
Run Code Online (Sandbox Code Playgroud)
目前,在这种形式下,当我将 reader 返回到 reader 时,没有任何价值。我已经完成了检查,并验证了在返回时,读者中包含正确的信息。然而读者没有价值观。我可能错过了一些完全愚蠢的东西。但我们将不胜感激。谢谢!
c# ×4
.net ×3
.net-2.0 ×2
datareader ×2
dataadapter ×1
datatable ×1
mysql ×1
performance ×1
yield ×1