Search code examples
c#.netextension-methodsienumerable

Best method to use IDataReader as IEnumerable<T>?


I need to use Linq on any IDataReader implementations like this

var c = sqlDataReader.AsEnumerable().Count();

Example:

public abstract class Test
{
    public abstract SqlDataReader GetSqlDataReader();

    public void Foo()
    {
        SqlDataReader sqlDataReader = GetSqlDataReader();
        IEnumerable<SqlDataReader> sqlEnumerable = sqlDataReader.AsEnumerable();
        var c = sqlEnumerable.Count();
        var s = sqlEnumerable.Sum();
        SqlDataReader first = sqlEnumerable.First();
        var t = first.GetSqlXml(10);
    }
}

What is the best way to write this. Please, write your snippet.


Solution

  • Try, this:

    public static class DataReaderExtension
    {
        public class EnumeratorWrapper<T>
        {
            private readonly Func<bool> moveNext;
            private readonly Func<T> current;
    
            public EnumeratorWrapper(Func<bool> moveNext, Func<T> current)
            {
                this.moveNext = moveNext;
                this.current = current;
            }
    
            public EnumeratorWrapper<T> GetEnumerator()
            {
                return this;
            }
    
            public bool MoveNext()
            {
                return moveNext();
            }
    
            public T Current
            {
                get { return current(); }
            }
        }
    
        private static IEnumerable<T> BuildEnumerable<T>(
                Func<bool> moveNext, Func<T> current)
        {
            var po = new EnumeratorWrapper<T>(moveNext, current);
            foreach (var s in po)
                yield return s;
        }
    
        public static IEnumerable<T> AsEnumerable<T>(this T source) where T : IDataReader
        {
            return BuildEnumerable(source.Read, () => source);
        }
    }