【问题标题】:Is there a way to use SqlBulkCopy without converting the data to a DataTable?有没有办法在不将数据转换为 DataTable 的情况下使用 SqlBulkCopy?
【发布时间】:2009-11-19 00:41:06
【问题描述】:

有没有办法在不将数据转换为 DataTable 的情况下使用 SqlBulkCopy?我在 RAM 中有一个对象列表 (List),我真的不想使用更多内存来创建 DataTable。是否可以在 List 上实现 IDataReader?

谢谢!

【问题讨论】:

    标签: c# sql-server sqlbulkcopy


    【解决方案1】:

    我当然想你可以。 BulkDataReader 需要架构信息;这就是为什么您不能简单地提供List。如果您设计一个实现IDataReader 的类,您将在您的GetSchemaTable 实现中提供它。

    我只会自己创建一个DataTable,除非我可以证明一个真正的内存问题可以证明实施是合理的。

    【讨论】:

      【解决方案2】:

      正如 Michael 所说,您当然可以实现 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 ) ) );
      

      【讨论】:

      • 只为 GetSchemaTable 使用(空)DataTable 是个好主意!使实现 IDataReader 变得非常容易。内存很便宜,但您根本无法为笔记本电脑添加 100 GB ;)
      【解决方案3】:

      当您将每个对象移动到 DataTable 中时,将其从 List 中删除,然后您就可以使用 SqlBulkCopy 并只需要一点额外的内存。

      然后,完成后,将其反转。

      就我个人而言,我会创建一个DataTable,因为内存很便宜。

      【讨论】:

        【解决方案4】:

        查看此链接http://code.msdn.microsoft.com/LinqEntityDataReader,您实际上可以从您的对象列表或任何支持 IQueryable 的对象中进行投影,该投影将被转换为可以传递给 SqlBulkCopy 对象的 DataReader。

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

        我认为这个库会派上用场,因为它可以为您节省一些工作。

        希望对你有帮助。

        【讨论】:

          猜你喜欢
          • 2019-08-27
          • 1970-01-01
          • 1970-01-01
          • 2013-07-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-01-29
          • 2020-02-06
          相关资源
          最近更新 更多