Есть ли способ использовать SqlBulkCopy без преобразования данных в DataTable? - PullRequest
8 голосов
/ 19 ноября 2009

Есть ли способ использовать SqlBulkCopy без преобразования данных в DataTable? У меня есть список объектов (List) в оперативной памяти, и я действительно не хочу использовать больше памяти для создания DataTable. Возможно ли реализовать IDataReader в списке?

Спасибо!

Ответы [ 4 ]

2 голосов
/ 19 ноября 2009

Я бы наверняка подумал, что ты мог. BulkDataReader требуется информация о схеме; вот почему вы не можете просто предоставить List. Если вы разрабатываете класс, который реализует IDataReader, вы предоставите это в своей реализации GetSchemaTable.

Я бы просто создал DataTable сам, если бы не смог продемонстрировать реальную проблему с памятью, которая оправдывала бы реализацию.

1 голос
/ 19 ноября 2009

Как говорит Майкл, вы, безусловно, можете реализовать IDataReader, который является наиболее эффективным способом сделать это, но для этого требуется дополнительная работа. Реализация GetSchemaTable - это довольно трудная задача, но это не так уж и плохо, если вы используете приведенный ниже код в качестве отправной точки.

        var table = new DataTable( "SchemaTable" );
        table.Locale = CultureInfo.InvariantCulture;

        table.Columns.Add( new DataColumn( SchemaTableColumn.ColumnName, typeof( string ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.ColumnOrdinal, typeof( int ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.ColumnSize, typeof( int ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.NumericPrecision, typeof( short ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.NumericScale, typeof( short ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.DataType, typeof( Type ) ) );
        table.Columns.Add( new DataColumn( SchemaTableOptionalColumn.ProviderSpecificDataType, typeof( Type ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.NonVersionedProviderType, typeof( int ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.ProviderType, typeof( int ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.IsLong, typeof( bool ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.AllowDBNull, typeof( bool ) ) );
        table.Columns.Add( new DataColumn( SchemaTableOptionalColumn.IsReadOnly, typeof( bool ) ) );
        table.Columns.Add( new DataColumn( SchemaTableOptionalColumn.IsRowVersion, typeof( bool ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.IsUnique, typeof( bool ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.IsKey, typeof( bool ) ) );
        table.Columns.Add( new DataColumn( SchemaTableOptionalColumn.IsAutoIncrement, typeof( bool ) ) );
        table.Columns.Add( new DataColumn( SchemaTableOptionalColumn.IsHidden, typeof( bool ) ) );
        table.Columns.Add( new DataColumn( SchemaTableOptionalColumn.BaseCatalogName, typeof( string ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.BaseSchemaName, typeof( string ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.BaseTableName, typeof( string ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.BaseColumnName, typeof( string ) ) );
        table.Columns.Add( new DataColumn( SchemaTableOptionalColumn.BaseServerName, typeof( string ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.IsAliased, typeof( bool ) ) );
        table.Columns.Add( new DataColumn( SchemaTableColumn.IsExpression, typeof( bool ) ) );
0 голосов
/ 09 июля 2013

Посмотрите на эту ссылку http://code.msdn.microsoft.com/LinqEntityDataReader,, вы можете перейти из списка объектов или всего, что поддерживает IQueryable, для создания проекции, которая будет преобразована в DataReader, который можно передать объекту SqlBulkCopy.

var q = from o in orders
         select new 
         {
           ID=o.ID,
           ShipDate=o.ShipDate,
           ProductName=o.Product.Name,
           ...
         }
IDataReader dr = q.AsDataReader();

Я думаю, эта библиотека пригодится, поскольку она сэкономит вам немного времени.

Надеюсь, это поможет.

0 голосов
/ 19 ноября 2009

Когда вы перемещаете каждый объект в DataTable, удаляете его из List, и затем вы можете использовать SqlBulkCopy с небольшой дополнительной памятью.

Затем, когда вы закончите, переверните его.

Лично я бы просто создал DataTable, так как память дешева.

...