Cómo obtener identidades de los registros de datos insertados utilizando una copia masiva de SQL

ado.net database identity sqlbulkcopy sql-server

Pregunta

Tengo una DataTable ADO.NET con aproximadamente 100,000 registros. En esta tabla hay una columna xyID que no tiene valores, porque la columna es una IDENTITY generada automáticamente en mi base de datos de SQL Server.

Necesito recuperar los ID generados para otros procesos. Estoy buscando una forma de copiar de forma masiva este DataTable en la base de datos de SQL Server, y dentro del mismo "paso" para "rellenar" mi DataTable con las ID generadas.

¿Cómo puedo recuperar los valores de identidad de los registros insertados en una tabla utilizando la clase SqlBulkCopy ?

Respuesta popular

Actualmente estoy haciendo algo como esto:

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

Tenga en cuenta que nuestro diseño de datos permite el filtrado de todos nuestros nuevos objetos mediante el uso de la ID de versión; Cada fila que estamos agregando tendrá el mismo ID de versión, y hemos eliminado previamente cualquier fila en la base de datos que ya tenía este ID de versión.

Sin embargo, mi consulta de selección está actualmente agotando el tiempo de espera en ExecuteReader, incluso con esa ventana de 10 minutos. Así que esta no es nuestra solución final.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué