Question

I have a generic list contains about six and a half million. I would like to insert this generic list to database by using sql bulk insert. But a datatable is necessary for using sql bulk insert. Convert generic list to datatable takes too much time. So how can I use sql bulk insert without using datatable ?

EDIT:

I use MSSQL SERVER and .NET FrameWork

I would like to just use it with a generic list.

Was it helpful?

Solution

I created a custom datareader that have been inherited IDataReader. I have achieved like below :

public class CustomDataReader<T> : IDataReader
    {
        private readonly IEnumerator<T> list;
        private readonly List<PropertyInfo> properties = new List<PropertyInfo>();

        public CustomDataReader(IEnumerable<T> list)
        {
            this.list = list.GetEnumerator();
            var props = typeof(T).GetProperties();
            foreach (var propertyInfo in props)
            {
                properties.Add(propertyInfo);
            }
        }

        #region IDataReader Members

        public void Close()
        {
            list.Dispose();
        }

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

        public DataTable GetSchemaTable()
        {
            throw new NotImplementedException();
        }

        public bool IsClosed
        {
            get { throw new NotImplementedException(); }
        }

        public bool NextResult()
        {
            throw new NotImplementedException();
        }

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

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

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            Close();
        }

        #endregion

        #region IDataRecord Members

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

        public bool GetBoolean(int i)
        {
            throw new NotImplementedException();
        }

        public byte GetByte(int i)
        {
            throw new NotImplementedException();
        }

        public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
        {
            throw new NotImplementedException();
        }

        public char GetChar(int i)
        {
            throw new NotImplementedException();
        }

        public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
        {
            throw new NotImplementedException();
        }

        public IDataReader GetData(int i)
        {
            throw new NotImplementedException();
        }

        public string GetDataTypeName(int i)
        {
            throw new NotImplementedException();
        }

        public DateTime GetDateTime(int i)
        {
            throw new NotImplementedException();
        }

        public decimal GetDecimal(int i)
        {
            throw new NotImplementedException();
        }

        public double GetDouble(int i)
        {
            throw new NotImplementedException();
        }

        public Type GetFieldType(int i)
        {
            return properties[i].PropertyType;
        }

        public float GetFloat(int i)
        {
            throw new NotImplementedException();
        }

        public Guid GetGuid(int i)
        {
            throw new NotImplementedException();
        }

        public short GetInt16(int i)
        {
            throw new NotImplementedException();
        }

        public int GetInt32(int i)
        {
            throw new NotImplementedException();
        }

        public long GetInt64(int i)
        {
            throw new NotImplementedException();
        }

        public string GetName(int i)
        {
            return properties[i].Name;
        }

        public int GetOrdinal(string name)
        {
            throw new NotImplementedException();
        }

        public string GetString(int i)
        {
            throw new NotImplementedException();
        }

        public object GetValue(int i)
        {
            return properties[i].GetValue(list.Current, null);
        }

        public int GetValues(object[] values)
        {
            throw new NotImplementedException();
        }

        public bool IsDBNull(int i)
        {
            throw new NotImplementedException();
        }

        public object this[string name]
        {
            get { throw new NotImplementedException(); }
        }

        public object this[int i]
        {
            get { throw new NotImplementedException(); }
        }

        #endregion
    }


public static void BulkInsert<T>(this IEnumerable<T> list, string connStr, string tableName)
{ 
    using (var reader = new CustomDataReader<T>(list))
    {
        using (var conn = new SqlConnection(connStr))
        {
            using (var sbc = new SqlBulkCopy(conn))
            {
                conn.Open();
                sbc.DestinationTableName = tableName;
                sbc.WriteToServer(reader);
                conn.Close();
            }
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top