简体   繁体   中英

SqlBulkCopy inserting in a table with Identity

this is my scenario: I have to import huge files in a table, so I used sqlBulkCopy cause other ways are too slowly.

This is an example of a file row:

String1|String2|String3|String4

And this is the table structure:

Id (Identity,PK)|Column1|Column2|Column3|Column4

I split row by '|', I create dataTable where I put every column of table ( Except Id ) reading infos by a configuration file:

DataColumn dc;
foreach (Tables.BulkColumn bc in columns)
{
    dc = new DataColumn();
    dc.DataType = bc.ColumnValueType;
    dc.ColumnName = bc.Name;
    dc.Unique = false;
    actualDataTable.Columns.Add(dc);
}

I load data from file to dataTable (data here are correct), initialize SqlBulkCopy and writeToServer:

SqlBulkCopy sbc = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.TableLock);
sbc.BulkCopyTimeout = 600;
sbc.WriteToServer(actualDataTable);

But, when I look in database, this is the inserted row:

IncrementedId|String2|String3|String4

It doesn't insert the Column1 value, it seems to work with columns index, but initializing dataColumns I set name explicitly.

Do you know how to solve it? The Id has to be inserted automatically writing other values correctly.

(I try moving Id as the last columns, it works correctly in this way, but I don't like this solution)

UPDATE

To insert data from txt to table, I read table structure from my configuration, eg

<table name="Table" file="D:\Progetti\TestArea\test\SqlBulkCopy\FP20150716003004.txt" incremental="false" active="true" identity="true">
      <field name="Column1" type="System.String" default="" key="false" allowsNull="true" length="50" />
 <!-- Other Fields --> ...

All fields are in the same order of the columns in input file. I split file rows and I put data into a DataRow:

dr[actualIndexColumnName] = string.IsNullOrEmpty(splitted[columnIndex]) ? tab.Columns[columnIndex].DefaultValue : splitted[columnIndex];

Where splitted[columnIndex] is actual input value, and when all columns of the row are filled I add this one to a DataTable

dt.Rows.Add(dr);

You are missing a column map for your SqlBulkCopy .

foreach (Tables.BulkColumn bc in columns)
{
   sbc.ColumnMapping.Add(bc.name);
}

I solved my problem using adding mappings to SqlBulkCopy in this way:

sbc.ColumnMappings.Clear();
int i = hasTableIdentity ? 1 : 0;
DataColumn dc;
foreach (Tables.BulkColumn bc in columns)
{
    dc = new DataColumn();
    dc.DataType = bc.ColumnValueType;
    dc.ColumnName = bc.Name;
    dc.Unique = false;
    sbc.ColumnMappings.Add(dc.ColumnName, i);
    actualDataTable.Columns.Add(dc);
    i++;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM