2010-03-24 13 views
9

Ho un ADO.NET DataTable con circa 100.000 record. In questa tabella è presente una colonna xyID che non contiene alcun valore, poiché la colonna è un IDENTITY generato automaticamente nel mio database SQL Server.Come ottenere le identità dei record di dati inseriti utilizzando la copia bulk SQL

Ho bisogno di recuperare gli ID generati per altri processi. Sto cercando un modo per copiare in massa questo DataTable nel database di SQL Server e all'interno dello stesso "passo" per "riempire" il mio DataTable con gli ID generati.

Come posso recuperare i valori di identità dei record inseriti in una tabella utilizzando la classe SqlBulkCopy?

risposta

2

Attualmente sto facendo qualcosa di simile:

DataTable objects = new DataTable(); 
DataColumn keyColumn = new DataColumn("name", typeof(string)); 
DataColumn versionColumn = new DataColumn("version", typeof(int)); 
versionColumn.DefaultValue = iVersionID; 

objects.Columns.Add(keyColumn); 
objects.Columns.Add(versionColumn); 

foreach (KeyValuePair<string, NamedObject> kvp in Directory) 
{ 
    NamedObject o = kvp.Value; 
    DataRow row = objects.NewRow(); 
    row[0] = o.Name; 
    objects.Rows.Add(row); 
} 

using (SqlBulkCopy updater = new SqlBulkCopy(conn, 
     SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.UseInternalTransaction, null)) 
{ 
    updater.DestinationTableName = "object_table"; 
    updater.WriteToServer(objects); 
} 

string sQuery = @"SELECT id, name FROM object_table WHERE version = @ver"; 
using (SqlCommand command = new SqlCommand(sQuery, conn)) 
{ 
    SqlParameter version = new SqlParameter("@ver", SqlDbType.Int, 4); 
    version.Value = versionID; 
    command.Parameters.Add(version); 

    command.CommandTimeout = 600; 

    using (SqlDataReader reader = command.ExecuteReader()) 
    { 
     while (reader.Read()) 
     { 
      string key = (string)reader[1]; 

      NamedObject item = Directory[key]; 
      item.ID = (int)reader[0]; 
     } 
    } 
} 

Si noti che il nostro design dei dati permette il filtraggio per tutti i nostri nuovi oggetti utilizzando l'ID di versione; ogni riga che stiamo aggiungendo avrà lo stesso id della versione e in precedenza abbiamo rimosso tutte le righe nel database che avevano già questo id versione.

Tuttavia, la mia query di selezione è attualmente scaduta in ExecuteReader, anche con quella finestra di 10 minuti. Quindi questa non è la nostra soluzione finale.

+0

In realtà abbiamo finito per mantenere questa soluzione, risolvendo i problemi di timeout impostando un processo per scadere dati vecchi e irrilevanti. Ho aggiunto una colonna timestamp e una colonna flag "keep" alla tabella delle versioni e ho aggiunto una modalità che rimuove tutti i dati associati a versioni più vecchie di un mese senza un flag "keep". I nostri problemi di timeout sono andati via dopo aver rimosso ~ 100 milioni di file. – Timbo

Problemi correlati