Ottenere SqlBulkCopy per onorare i nomi delle colonne

c# sqlbulkcopy tsql

Domanda

Sono in procinto di convertire alcune routine di reporting basate su stored procedure per l'esecuzione in C #. L'idea generale è quella di utilizzare tutte le meraviglie di C # /. NET Framework e quindi restituire i risultati nel DB. Tutto è andato a gonfie vele, tranne per un problema che ho incontrato ieri e risolto oggi.

Per eseguire l'importazione, sto programmaticamente creando un DataTable e utilizzando SqlBulkCopy per spostare i risultati sul server.

per esempio

 DataTable detail = new DataTable();
 detail.Columns.Add(new DataColumn("Stock", Type.GetType("System.Decimal")));
 detail.Columns.Add(new DataColumn("Receipts", Type.GetType("System.Decimal")));
 detail.Columns.Add(new DataColumn("Orders", Type.GetType("System.Decimal")));

La tabella di importazione aveva i campi nel seguente ordine.

...
Stock decimal(18,4),
Orders decimal(18,4),
Receipts decimal(18,4)
...

In sostanza, il valore per Receipts andava agli ordini e viceversa.

Evidentemente, questo è dovuto al fatto che SqlBulkCopy non sembra onorare il nome della colonna che gli ho detto di popolare, ma solo per posizione ordinale.

Questo è un problema per me poiché usiamo il confronto SQL di Redgate. Quando si spostano le modifiche da un database a un altro, la posizione ordinale delle colonne non viene necessariamente mantenuta. (Ad esempio, se si inserisce una nuova colonna come terzo campo ordinale, SQL Compare la aggiungerà semplicemente alla tabella su una sincronizzazione, rendendola l'ultima colonna).

Questo mette seriamente in crisi la mia soluzione. Ora, queste sono solo tabelle di "importazione", quindi se necessario, posso rilasciarle e ricrearle come parte di qualsiasi script di migrazione con le posizioni ordinali intatte. Preferirei non farlo comunque.

C'è un modo per forzare SqlBulkCopy ad onorare i nomi delle colonne che gli dici di riempire?

Risposta accettata

Da http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.columnmappings.aspx :

Tuttavia, se i conteggi delle colonne sono diversi o le posizioni ordinali non sono coerenti, è necessario utilizzare ColumnMappings per assicurarsi che i dati vengano copiati nelle colonne corrette.

Per il codice di esempio vedi "Mapping Columns" a http://www.sqlteam.com/article/use-sqlbulkcopy-to-quickly-load-data-from-your-client-to-sql-server


Risposta popolare

Ecco una soluzione per risolvere questo 'bug'.

L'impostazione predefinita è mappare per ordinale / posizione.

Nel mio caso stavo caricando da un foglio di calcolo con colonne in ordine casuale. ecco una soluzione rapida (table è il mio DataTable che è 'fuori dall'ordine ordinale' e bulkCopy è l'oggetto SqLBulkCopy)

foreach (DataColumn col in table.Columns)
{
    bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
}

Come puoi vedere, lo sto solo costringendo a riordinare per nome, anche se i nomi sono IDENTICI.



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché