这是我的情景: 我必须在表中导入大文件,所以我使用sqlBulkCopy导致其他方法太慢。
这是文件行的示例:
String1|String2|String3|String4
这是表结构:
Id (Identity,PK)|Column1|Column2|Column3|Column4
我将行拆分为'|',我创建了dataTable,其中我将表的每一列(除了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);
}
我将数据从文件加载到dataTable(这里的数据是正确的),初始化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 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);
答案 0 :(得分:2)
您遗失了SqlBulkCopy
的{{3}}。
foreach (Tables.BulkColumn bc in columns)
{
sbc.ColumnMapping.Add(bc.name);
}
答案 1 :(得分:1)
我通过以这种方式向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++;
}