Я не вижу, как ваше предлагаемое расширение поможет вам, поскольку вы получаете только нумерацию, содержащую тот же экземпляр IDataReader
для каждой строки чтения.
Я не уверен, есть ли хороший способ совместить IDataReader
с LINQ, но вы можете что-то вроде этого:
public static IEnumerable<Dictionary<string, object>> ToEnumerable(this IDataReader reader)
{
while (reader.Read())
{
Dictionary<string, object> result = new Dictionary<string, object>();
for (int column = 0; column < reader.FieldCount; column++)
result.Add(reader.GetName(column), reader.GetValue(column));
yield return result;
}
}
Это возвращает последовательность словарей (один словарь для каждой строки), который сопоставьте имя столбца с объектом в этой ячейке.
К несчастью, вы теряете безопасность типов и создаете накладные расходы памяти. Конкретная реализация по-прежнему будет зависеть от того, чего вы действительно хотите достичь. Лично я всегда использую только индекс столбца вместо имени.
То есть, я думаю, что лучший подход по-прежнему использовать IDataReader
непосредственно для создания Pocos и использовать это Pocos с LINQ:
IEnumerable<string> GetSomeColValue(IDataReader reader)
{
while(reader.Read())
yield return reader.GetString(reader.GetOrdinal("SomeColName"));
}
Конечно, это сокращенный пример. В реальном коде я полностью считывал все данные из читателя и закрывал/удалял экземпляр читателя внутри метода, который вызывал ExecuteReader
, прежде чем что-либо вернуть.
Я думаю, что работа не будет проблемой здесь, его просто генерируя состояние-машины для выхода. Помимо этого я бы рекомендовал выставлять 'IDataRecord' вместо' IDataReader' (наследование), иначе вы бы разоблачили 'Read'-method (чтобы пользователи могли вызвать этот метод и испортить набор результатов). – Caramiriel