Comment spécifier des clés étrangères entre deux DataTables dans une opération de copie en bloc SQL?

asp.net c# datatable sqlbulkcopy

Question

J'ai deux DataTables A et B. A est la table parente. Les lignes en B contiennent un champ ParentId qui référence A.

Je souhaite regrouper les éléments A et B séparément. Après avoir inséré A, comment définir le ParentId dans les lignes enfants correspondantes dans B?

Mettre à jour:

J'ai le code suivant pour créer les DataTables:

    var a= new DataTable("A");

    DataColumn id= new DataColumn("Id", typeof(int));
    billablePriceMapId.AutoIncrement = true;
    billable.Columns.Add(id);

    DataColumn fee = new DataColumn("Fee", typeof(decimal));
    billable.Columns.Add(fee);

    DataColumn[] keys = new DataColumn[1];
    keys[0] = id;
    billable.PrimaryKey = keys;

Pour la table enfant:

    var b= new DataTable("B");

    DataColumn id= new DataColumn("Id", typeof(int));
    billablePriceMapId.AutoIncrement = true;
    billable.Columns.Add(id);

    DataColumn parentId= new DataColumn("ParentId", typeof(int));
    billable.Columns.Add(parentId);

    DataColumn[] keys = new DataColumn[1];
    keys[0] = id;
    billable.PrimaryKey = keys;

Je n'ai pas mis en place de relation entre les deux tables. Je voudrais savoir comment je pourrais le faire de la bonne façon.

Voici le code que j'utilise pour l'insertion en bloc:

using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.Default, transaction))
                    {
                        try
                        {
                            bulkCopy.DestinationTableName = "dbo.A";
                            bulkCopy.WriteToServer(a);

                            bulkCopy.DestinationTableName = "dbo.B";
                            bulkCopy.WriteToServer(b);
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex, "Bulk copy operation failed.");
                        }
                    }

Réponse d'expert

SqlBulkCopy ne SqlBulkCopy pas les valeurs d'identité. Donc, à moins que votre table A contienne une autre colonne unique, telle qu'un "Code" pour permettre de perfectionner un SELECT vous ne pourrez pas récupérer les valeurs d'identité générées.

Disclaimer : Je suis le propriétaire du projet Bulk Operations

Cette bibliothèque n'est pas libre mais permet de sortir des valeurs d'identité. Il utilise sous le capot SqlBulkCopy avec Temporary Table pour permettre cette fonctionnalité

using (var bulkCopy = new BulkOperation(connection))
{
    bulkCopy.Transaction = transaction;
    bulkCopy.DestinationTableName = "dbo.A";

    bulkCopy.ColumnMappings.Add("Id", ColumnMappingDirectionType.Output);
    bulkCopy.ColumnMappings.Add("Col1");
    bulkCopy.ColumnMappings.Add("Col2");
    bulkCopy.BulkInsert(a);

    // Copy identity value in `Id` from table A to `ParentId` in table B
    // ...code...
}

Réponse populaire

Je n'utiliserais pas l'identité pour lier les deux tables, mais plutôt un GUID pour les lier. Comme ça :

var a= new DataTable("A");

DataColumn guid= new DataColumn("Guid", typeof(Guid));
billable.Columns.Add(Guid.NewGuid());

DataColumn id= new DataColumn("Id", typeof(int));
billablePriceMapId.AutoIncrement = true;
billable.Columns.Add(id);

DataColumn fee = new DataColumn("Fee", typeof(decimal));
billable.Columns.Add(fee);

DataColumn[] keys = new DataColumn[1];
keys[0] = id;
billable.PrimaryKey = keys;

Et ensuite pour les enfants

var b= new DataTable("B");

DataColumn id= new DataColumn("Id", typeof(int));
billablePriceMapId.AutoIncrement = true;
billable.Columns.Add(id);

DataColumn parentId= new DataColumn("ParentGuid", typeof(Guid));
billable.Columns.Add(parentGuid);

DataColumn[] keys = new DataColumn[1];
keys[0] = id;
billable.PrimaryKey = keys;

Cela signifie que vous savez ce que le lien sera avant les insertions, avant que l'identité soit générée.



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