Converting IEnumerable to IDataReader

2011-01-30 15:09:06 +0000

If you’ve got an enumerable, and you want to pass it to SqlBulkCopy, you can turn it into an IDataReader. Something like the following might be useful:

static class DataReaderExtensions
{
    public static IDataReader AsDataReader(this IEnumerable source, int fieldCount, Func<TSource, int, object> getValue)
    {
        return EnumerableDataReader.Create(source, fieldCount, getValue);
    }
}

internal static class EnumerableDataReader
{
    public static IDataReader Create(IEnumerable source, int fieldCount, Func<TSource, int, object> getValue)
    {
        return new EnumerableDataReader(source.GetEnumerator(), fieldCount, getValue);
    }
}

internal class EnumerableDataReader : IDataReader
{
    private readonly IEnumerator _source;
    private readonly int _fieldCount;
    private readonly Func<TSource, int, object> _getValue;

    internal EnumerableDataReader(IEnumerator source, int fieldCount, Func<TSource, int, object> getValue)
    {
        _source = source;
        _getValue = getValue;
        _fieldCount = fieldCount;
    }

    public void Dispose()
    {
        // Nothing.
    }

    public object GetValue(int i)
    {
        return _getValue(_source.Current, i);
    }

    public int FieldCount
    {
        get { return _fieldCount; }
    }

    public bool Read()
    {
        return _source.MoveNext();
    }
}</pre>

Note that there are several more methods on IDataReader that you’ll need to implement. Fortunately, they never seem to be called in this scenario, so I had them all throw NotImplementedException().