Хоча розуміння того, як 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;
}
}
Я спробував той самий приклад у зразку консольного додатка і під час налагодження помітив, що остаточний блок GetRecords()
не виконується. Як я можу забезпечити закриття з'єднання БД? Чи є кращий спосіб, ніж використання yield
ключового слова? Я намагаюся створити спеціальний клас, який буде відповідати за виконання вибраних SQL та збережених процедур у БД і повертатиме результат. Але я не хочу повертати DataReader абоненту. Також я хочу переконатися, що з'єднання буде закрито у всіх сценаріях.
Редагування Змінено відповідь на відповідь Бена, оскільки неправильно розраховувати, що користувачі методу правильно використовуватимуть метод, а щодо з'єднання з БД це буде дорожче, якщо метод викликається кілька разів без причини.
Дякую Якобу та Бену за детальне пояснення.