SqlBulkCopy 插入 table with Identity

SqlBulkCopy inserting in a table with Identity

这是我的场景: 我必须在 table 中导入大文件,所以我使用了 sqlBulkCopy,因为其他方法太慢了。

这是文件行的示例:

String1|String2|String3|String4

这是 table 结构:

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

我用'|'分割行,我创建数据表,我把table的每一列(除了Id)通过配置文件读取信息:

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);
}

我将数据从文件加载到数据表(这里的数据是正确的),初始化 SqlBulkCopy 和 writeToServer:

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

但是,当我查看数据库时,这是插入的行:

IncrementedId|String2|String3|String4

它不插入 Column1 值,它似乎与列索引一起使用,但初始化 dataColumns 我明确设置了名称。

你知道怎么解决吗?必须自动插入 Id 并正确写入其他值。

(我尝试将 Id 移动到最后一列,这样可以正常工作,但我不喜欢这种解决方案)

更新

为了将数据从 txt 插入到 table,我从我的配置中读取了 table 结构,例如

<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 --> ...

所有字段的顺序与输入文件中列的顺序相同。 我拆分文件行并将数据放入 DataRow:

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

其中 splitted[columnIndex] 是实际输入值,当该行的所有列都被填充时,我将其添加到 DataTable

dt.Rows.Add(dr);

您的 SqlBulkCopy 缺少一个 column map

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

我通过以这种方式将映射添加到 SqlBulkCopy 解决了我的问题:

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++;
}