Понимая, как yield
работает ключевое слово, я наткнулся на link1 и link2 в StackOverflow, который поддерживает использование yield return
итерации по DataReader, и это также удовлетворяет мои потребности. Но меня удивляет, что произойдет, если я буду использовать, yield return
как показано ниже, и если я не буду перебирать весь DataReader, будет ли соединение с БД оставаться открытым навсегда?
IEnumerable<IDataRecord> GetRecords()
{
SqlConnection myConnection = new SqlConnection(@"...");
SqlCommand myCommand = new SqlCommand(@"...", myConnection);
myCommand.CommandType = System.Data.CommandType.Text;
myConnection.Open();
myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection);
try
{
while (myReader.Read())
{
yield return myReader;
}
}
finally
{
myReader.Close();
}
}
void AnotherMethod()
{
foreach(var rec in GetRecords())
{
i++;
System.Console.WriteLine(rec.GetString(1));
if (i == 5)
break;
}
}
Я попробовал тот же пример в образце консольного приложения и заметил при отладке, что блок finally GetRecords()
не выполняется. Как я могу обеспечить закрытие соединения с БД? Есть ли лучший способ, чем использовать yield
ключевое слово? Я пытаюсь разработать собственный класс, который будет отвечать за выполнение отдельных SQL и хранимых процедур в БД и будет возвращать результат. Но я не хочу возвращать DataReader вызывающей стороне. Также я хочу убедиться, что соединение будет закрыто во всех сценариях.
Изменить Изменен ответ на ответ Бена, так как неверно ожидать, что вызывающие методы будут правильно использовать метод, и в отношении соединения с БД будет дороже, если метод вызывается несколько раз без какой-либо причины.
Спасибо Якобу и Бену за подробное объяснение.