Есть ли способ использовать массовую вставку sql без использования данных из общего списка?

У меня общий список содержит около шести с половиной миллионов. Я хотел бы вставить этот общий список в базу данных с помощью массовой вставки sql. Но для использования массовой вставки sql необходима таблица данных. Преобразование общего списка в таблицу данных занимает слишком много времени. Итак, как я могу использовать массовую вставку sql без использования datatable?

ИЗМЕНИТЬ:

Я использую MSSQL SERVER и .NET FrameWork

Я хотел бы просто использовать его с общим списком.


person sinanakyazici    schedule 10.03.2014    source источник
comment
Какая СУБД, mysql, сервер sql и т. д. и какая структура?   -  person Tony Hopkinson    schedule 11.03.2014
comment
Извините, я забыл их написать. Я отредактировал свой вопрос.   -  person sinanakyazici    schedule 11.03.2014
comment
Под массовой вставкой вы подразумеваете вставку большого количества данных или собственное средство массовой вставки SQL Server, которое работает из файла. Почему у вас в памяти 6,5 миллионов записей, на первый взгляд это не кажется мудрым поступком.   -  person Tony Hopkinson    schedule 11.03.2014
comment
Да, я хотел сказать, чтобы вставить большую часть данных. Я не использую файл . Я создаю новый список, используя некоторый процесс в памяти. Я попытался вставить каждую запись в базу данных. Это занимает гораздо больше времени, чем массовая вставка. Что я могу сделать еще?   -  person sinanakyazici    schedule 11.03.2014
comment
Посмотрите на команду массовой вставки sql server, это не дай мне, так как ей нужен файл, и этот файл должен быть доступен для учетных записей, под которыми работает служба, но это намного быстрее. С вашим нынешним подходом влияние, которое вы можете оказать, сильно ограничено.   -  person Tony Hopkinson    schedule 11.03.2014
comment
В этом случае не нужно ли преобразовывать или записывать в файл общий список? Это также не будет терять время?   -  person sinanakyazici    schedule 12.03.2014
comment
Ну, конечно, это займет время, далеко не так много, как отправка вставок на сервер по одной за раз. Такое количество записей на стороне клиента нелегко восстановить, дешевого варианта нет.   -  person Tony Hopkinson    schedule 12.03.2014


Ответы (1)


Я создал пользовательское средство чтения данных, унаследованное от IDataReader. Я достиг, как показано ниже:

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();
            }
        }
    }
}
person sinanakyazici    schedule 18.05.2014