11
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

IEnumerable から IDataReader へ変換

Posted at

#初めに
C#で Bulk Insert のサンプルを作成して利用しているが、データの変換が必要な場合、DataSetにいれる必要がでてメモリが必要になる。
IEnumerableを使えば、yield return でデータを返すとメモリをあまり使用せずに実行ができる。
調べるとブログ「Converting IEnumerable to IDataReader」を見つけた。
SqlBulkCopy を使うための最小限のIDataReaderの実装が載っていて大変参考になった。
#サンプルコード

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;
using System.Threading.Tasks;
using SampleIDataReader.Properties;

namespace SampleIDataReader
{
    static class DataReaderExtensions
    {
        public static IDataReader AsDataReader<TSource>(this
IEnumerable<TSource> source)
        {
            return EnumerableDataReader.Create(source);
        }
    }

    internal static class EnumerableDataReader
    {
        public static IDataReader Create<TSource>(IEnumerable<TSource>
source)
        {
            return new EnumerableDataReader<TSource>(source);
        }

    }

    internal class EnumerableDataReader<TSource> : IDataReader
    {
        private readonly IEnumerator<TSource> _source;
        private readonly List<PropertyInfo> listProp = new
List<PropertyInfo>();

        internal EnumerableDataReader(IEnumerable<TSource> source)
        {
            _source = source.GetEnumerator();
            foreach (var prop in typeof(TSource).GetProperties())
            {
                listProp.Add(prop);
            }
        }

        public bool Read()
        {
            return _source.MoveNext();
        }

        public void Close()
        {
        }

        public void Dispose()
        {
        }

        public int FieldCount
        {
            get { return listProp.Count; }
        }

        public object GetValue(int i)
        {
            return listProp[i].GetValue(_source.Current);
        }

        public int Depth
        {
            get { throw new NotImplementedException(); }
        }

        // 残りのメソッドもDepthと同様 NotImplementedException を発生させている

    }

    class SampleTable
    {
        public int Field1 { get; set; }
        public string Field2 { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var arr = new SampleTable[]
            {
                new SampleTable{Field1 = 1, Field2 = "Field1"},
                new SampleTable{Field1 = 2, Field2 = "Field2"},
                new SampleTable{Field1 = 3, Field2 = "Field3"},
            };

            using (var bc = new
SqlBulkCopy(Settings.Default.xxxConnectionString))
            {
                bc.DestinationTableName = "dbo.SampleTable";
                bc.WriteToServer(arr.AsDataReader());
            }

        }
    }
}




11
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?