2015-07-21 4 views
1

это мой сценарий: Мне нужно импортировать огромные файлы в таблицу, поэтому я использовал sqlBulkCopy, потому что другие способы слишком медленны.SqlBulkCopy вставка в таблицу с идентификатором

Это пример файла строки:

String1|String2|String3|String4 

И это структура таблицы:

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

я разделить строку на «|», я создаю DataTable, где я ставлю каждый столбец таблицы (исключением Id) чтение Infos с помощью файла конфигурации:

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 

Это Безразлично 't вставить значение Column1, похоже, работает с индексом столбцов, но инициализируя dataColumns, я задаю имя явно.

Вы знаете, как его решить? Идентификатор должен быть вставлен автоматически, записывая другие значения правильно.

(я стараюсь двигаться Id в последних столбцах, она работает правильно, таким образом, но мне не нравится это решение)

UPDATE

Чтобы вставить данные из TXT в таблице I прочитайте структуру таблицы из моей конфигурации, например

<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]; 

Где расщепляются [ColumnIndex] является фактическим значением входного сигнала, и, когда все столбцы строки заполнены добавить эту к DataTable

dt.Rows.Add(dr); 
+0

Возможный дубликат http://stackoverflow.com/questions/6651809/sqlbulkcopy-insert-with-identity-column , Этот вопрос в основном связан с тем, как «SqlBulkCopy» имеет дело с столбцами идентичности. (Установите 'SqlBulkCopyOptions.KeepIdentity = true', возможно?) – stakx

+0

@stakx Я попытался установить SqlBulkCopyOptions.KeepIdentity = true, но он дает мне ошибку System.FormatException, которая, похоже, работает с использованием индексов (Id is int, column1 is nvarchar) – SamDroid

+0

Возможно, вам стоит остановиться и подумать, почему 'column1' является' nvarchar'. Разве это не должно быть 'int', как в реальной схеме базы данных?Если это так, означает ли это, что, возможно, вам нужно изменить свой код, который создает 'DataTable' (например, добавить что-то вроде' int.Parse' после 'string.Split')? – stakx

ответ

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

Вам не хватает column map для вашего SqlBulkCopy.

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

Ваше решение работает, но не существует. Добавить перегрузки, которые принимают только один параметр , поэтому я использовал перегрузку, которая принимает имя столбца, columnPosition. – SamDroid

Смежные вопросы