79 votes

SqlBulkCopy Insertion avec colonne d'identité

J'utilise le SqlBulkCopy pour insérer quelques millions de lignes générées dans une base de données. Le seul problème est que la table dans laquelle j'insère l'objet possède une colonne d'identité. J'ai essayé de définir le paramètre SqlBulkCopyOptions a SqlBulkCopyOptions.KeepIdentity et en fixant la colonne d'identité à 0 's, DbNull.Value y null . Aucune d'entre elles n'a fonctionné. J'ai l'impression de passer à côté de quelque chose de très simple, si quelqu'un pouvait m'éclairer, ce serait fantastique. Merci.

modifier Pour clarifier, je n'ai pas les valeurs d'identité définies dans le fichier d'identité de l'utilisateur. DataTable Je suis en train d'importer. Je veux qu'ils soient générés dans le cadre de l'importation.

modifier 2 Voici le code que j'utilise pour créer la base SqlBulkCopy objet.

SqlBulkCopy sbc = GetBulkCopy(SqlBulkCopyOptions.KeepIdentity);
sbc.DestinationTableName = LOOKUP_TABLE;

private static SqlBulkCopy GetBulkCopy(SqlBulkCopyOptions options = 
    SqlBulkCopyOptions.Default) 
{
    Configuration cfg = WebConfigurationManager.OpenWebConfiguration("/RSWifi");
    string connString =
    cfg.ConnectionStrings.ConnectionStrings["WifiData"].ConnectionString;
    return new SqlBulkCopy(connString, options);
}

51voto

Jason Points 125291

Pour que la table de destination attribue l'identité, NE PAS utiliser le SqlBulkCopyOptions.KeepIdentity option. Au lieu de cela, Ne le fais pas. mettre en correspondance l'identité de la source, et Ne le fais pas. l'extraire de la source pour l'envoyer à SqlBulkCopy .

1 votes

En fait, j'ai besoin que les valeurs d'identité soient générées au moment de l'insertion, si cela peut aider.

4 votes

Oh, vous voulez que la destination attribue la valeur ? Ce n'était pas du tout clair dans votre question. N'utilisez pas SqlBulkCopyOptions.KeepIdentity ! Désactivez cette fonction, et ne l'incluez pas dans le mappage ni quand vous tirez de source .

0 votes

Oh, j'ai été confondu par la documentation When not specified, identity values are assigned by the destination. Je pensais que cela signifiait quand une valeur n'était pas spécifiée :(

34voto

Wim Points 1445

Remplir le ColumnMapping de la BulkCopy et ne mappe pas la colonne d'identité. La colonne d'identité sera générée par la base de données cible.

1 votes

Cela vient de résoudre un problème qui me tourmentait depuis plusieurs heures.

0 votes

Cela m'a aidé car ma source et ma destination avaient un nombre différent de colonnes. Les données sources comportaient des colonnes utilisées pour l'affichage des données dans un format particulier. Cela signifiait également des données dupliquées dans la base de données. J'ai donc utilisé la collection ColumnMappings pour ignorer certaines colonnes des données source qui n'avaient pas besoin d'être enregistrées dans la base de données.

5 votes

Je n'ai pas vraiment compris cette réponse, mais je pense que c'est la réponse à mon problème. Si vous n'ajoutez pas la colonne d'identité dans le fichier DataTable par exemple returnVal.Columns.Add("Id", typeof(int)); alors vous avez un problème de cartographie. Cette colonne ne devrait pas être affectée d'une valeur, donc Ne le fais pas. ajouter dataRow["id"] = ...etc.

5voto

JNK Points 32743

Vous avez deux options -

1 - utiliser KeepIdentity et préserver la source Identity valeurs.

2 - Ne pas cartographier le Identity champ. Si vous n'essayez pas d'attribuer une valeur, la table cible en attribuera une automatiquement.

1 votes

Ne pas assigner une variable est équivalent à assigner DbNull.Value . Je reçois toujours le même Column 'Id' does not allow DBNull.Value. IOE :( Ou alors, vous voulez dire qu'il ne faut même pas inclure l'élément Id dans ma rubrique DataTable ?

0 votes

@Flying - avez-vous éteint KeepIdentity ? Il faut que ce soit FALSE pour que la cible puisse attribuer une valeur.

0 votes

J'ai ajouté le code que j'utilise pour créer le fichier SqlBulkCopy objet. Je ne vois pas de champ/propriété appelé KeepIdentity à régler.

1voto

user2522747 Points 11

Oui, vous avez raison d'utiliser SqlBulkCopyOptions.KeepIdentity Pour notre besoin, je fais de la même manière pour préserver le champ d'identité dans ma table, il suffit de créer une colonne supplémentaire dans votre objet datatable avec le reste de vos colonnes nécessaires et de passer des valeurs nulles à cette colonne, puis la table gère automatiquement l'identité.

-2voto

Vinay K Points 1

Cause :- Il y avait quelques lignes vides dans l'excel à la fin des données, qui ressemblent éventuellement à des lignes vides. Bulk upload essayait de charger ces lignes vides dans la table.

Solution Sélectionnez uniquement les lignes qui contiennent des données et copiez les données dans la nouvelle feuille. Disons que vous avez vos données dans la 'Feuille 1', déplacez-les vers la 'Feuille 2' et supprimez la 'Feuille 1'.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X