Справочная информация: у меня есть куча строк, которые я получаю из базы данных, и я хочу их вернуть. Традиционно это будет примерно так:
public List<string> GetStuff(string connectionString)
{
List<string> categoryList = new List<string>();
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
string commandText = "GetStuff";
using (SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection))
{
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlConnection.Open();
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
while (sqlDataReader.Read())
{
categoryList.Add(sqlDataReader["myImportantColumn"].ToString());
}
}
}
return categoryList;
}
Но потом я думаю, что потребитель захочет перебирать элементы и не заботится о многом другом, и я хотел бы не включать себя в Список, как таковой, поэтому, если я верну IEnumerable все хорошо / гибкий. Поэтому я подумал, что мог бы использовать дизайн типа «возвращение дохода», чтобы справиться с этим ... что-то вроде этого:
public IEnumerable<string> GetStuff(string connectionString)
{
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
string commandText = "GetStuff";
using (SqlCommand sqlCommand = new SqlCommand(commandText, sqlConnection))
{
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlConnection.Open();
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
while (sqlDataReader.Read())
{
yield return sqlDataReader["myImportantColumn"].ToString();
}
}
}
}
Но теперь, когда я читаю немного больше о доходности (на сайтах, подобных этому ... msdn, похоже, не упоминал об этом), это, очевидно, ленивый оценщик, который держит состояние популяции в ожидании кого-то, запрашивающего следующее значение, а затем только запускающего его, пока оно не вернет следующее значение.
Это выглядит нормально в большинстве случаев, но с вызовом БД это звучит немного рискованно. В качестве несколько надуманного примера, если кто-то запрашивает IEnumerable из того, что я заполняю из вызова БД, проходит через половину этого, а затем застревает в цикле ... насколько я вижу, происходит мое соединение с БД оставаться открытым навсегда.
Похоже, что в некоторых случаях возникает проблема, если итератор не завершает работу ... я что-то упустил?