Reply to comment

roger's picture

Converting IEnumerable<T> to IDataReader

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<TSource>(this IEnumerable<TSource> source, int fieldCount, Func<TSource, int, object> getValue)
    {
        return EnumerableDataReader.Create(source, fieldCount, getValue);
    }
}

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

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

    internal EnumerableDataReader(IEnumerator<TSource> 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();
    }
}

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().

Reply

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <b> <blockquote> <br> <code> <dd> <dl> <dt> <hr> <h1> <h2> <h3> <i> <img> <li> <ol> <p> <pre> <table> <td> <th> <tr> <tt> <u> <ul>
  • Images can be added to this post.

More information about formatting options