Come ottenere le identità dei record di dati inseriti utilizzando la copia bulk di SQL

ado.net database identity sqlbulkcopy sql-server

Domanda

Ho un DataTable ADO.NET con circa 100.000 record. In questa tabella c'è una colonna xyID che non contiene valori, perché la colonna è un IDENTITY generato automaticamente nel mio database SQL Server.

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 popolare

Attualmente sto facendo qualcosa del genere:

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 la nostra progettazione dei dati consente il filtraggio per tutti i nostri nuovi oggetti utilizzando l'ID della 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.



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é