Comment obtenir les identités des enregistrements de données insérés à l'aide d'une copie en bloc SQL

ado.net database identity sqlbulkcopy sql-server

Question

J'ai un ADO.NET DataTable avec environ 100 000 enregistrements. Dans cette table, il existe une colonne xyID qui ne contient aucune valeur, car cette colonne est une IDENTITY générée automatiquement dans ma base de données SQL Server.

J'ai besoin de récupérer les identifiants générés pour d'autres processus. Je cherche un moyen de copier en bloc ce DataTable dans la base de données SQL Server et, dans la même "étape", de "remplir" mon DataTable avec les ID générés.

Comment récupérer les valeurs d'identité des enregistrements insérés dans une table à l'aide de la classe SqlBulkCopy ?

Réponse populaire

Je suis en train de faire quelque chose comme ça:

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

Notez que notre conception de données permet de filtrer tous nos nouveaux objets à l'aide de l'ID de version. chaque ligne que nous ajoutons aura le même identifiant de version et nous avons précédemment supprimé toutes les rangées de la base de données contenant déjà cet identifiant de version.

Cependant, ma requête sélectionnée est en cours de traitement dans ExecuteReader, même avec cette fenêtre de 10 minutes. Donc, ce n'est pas notre solution finale.



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi