web-dev-qa-db-fra.com

"Impossible d'insérer une valeur explicite pour la colonne d'identité dans la table lorsque IDENTITY_INSERT est défini sur OFF" avec clé composite

Nous avons récemment ajouté un nouveau "niveau" à notre base de données. Nous avons ajouté une clé "ID_entreprise" qui doit se situer au-dessus/avant le champ Identité d’ID existant dans les tables de la base de données.

Par exemple, si une table avait un ID puis des champs, elle a maintenant Company_ID, puis un ID, puis les champs. L'idée est que cela permet à l'ID de s'incrémenter automatiquement pour chaque valeur Company_ID différente fournie à la fonctionnalité (ID_entreprise 1 peut avoir l'ID 1, 2, 3, etc.; ID_entreprise 2 peut avoir l'ID 1, 2, 3, etc.).

Le champ d'auto-incrémentation reste comme ID. Un exemple de table est:

    [dbo].[Project](
      [Company_ID] [int] NOT NULL,
      [ID] [int] IDENTITY(1,1) NOT NULL,
      [DescShort] [varchar](100) NULL,
      [TypeLookUp_ID] [int] NULL,
      [StatusLookUp_ID] [int] NULL,
      [IsActive] [bit] NOT NULL,
    CONSTRAINT [PK_Project] PRIMARY KEY CLUSTERED 
    (
      [Company_ID] ASC,
      [ID] ASC
    )

Avant l'introduction de Company_ID, pour effectuer une opération CREATE, nous avons simplement renseigné les champs DescShort, TypeLookUp_ID, StatusLookUp_ID et IsActive, et avons laissé l'identifiant de ce qu'il était par défaut, éventuellement 0.

L'enregistrement a été enregistré avec succès et l'ID a été rempli automatiquement par la base de données, puis utilisé pour exécuter un SHOW via une vue, etc. 

Maintenant, cependant, nous voulons définir Company_ID sur une valeur spécifiée, laisser ID et renseigner les champs comme auparavant.

    _db.Project.Add(newProject);
    _db.SaveChanges();

Oui, nous voulons spécifier la valeur Company_ID. Nous voulons que l'ID soit automatiquement renseigné, comme précédemment .. Nous obtenons le message d'erreur suivant:

Impossible d'insérer une valeur explicite pour la colonne d'identité dans la table "Projet" lorsque IDENTITY_INSERT est défini sur OFF

Est-ce causé par la spécification du Company_ID ou par le champ ID? Savez-vous comment nous pouvons résoudre ce problème?

12
and_E

Après avoir dormi, j’ai trouvé ceci, pour Visual Studio c # code: [DatabaseGenerated(DatabaseGeneratedOption.Identity)]. Ceci (dans mes mots), défini pour chacun de mes champs ID, indique à Visual Studio que le champ est une identité et qu'il faut le laisser seul lors de l'envoi de valeurs à la base de données. Lorsque Company_ID apparaît en premier et a une valeur, indiquer à Visual Studio qu'il existe un champ Identity ailleurs permet à la fonction _db.Project.Add(newProject);, puis à la fonction _db.SaveChanges(); de fonctionner comme il convient . Cette partie de la réponse concerne le côté Visual Studio. Je comprends les exigences SQL de IDENTIY_INSERT donc merci à @ matt-thrower, @ steve-pettifer et aux autres personnes qui ont contribué.

10
and_E

Le problème est sur l'ID. Si vous définissez un champ comme IDENTITY, vous ne pouvez normalement pas lui attribuer de valeur. La propriété IDENTITY le marque comme permettant à la base de données d'attribuer automatiquement une valeur incrémentielle à la colonne.

Pour résoudre ce problème, supprimez la propriété IDENTITY automatique de ID (si vous souhaitez l'incrémenter automatiquement, vous pouvez toujours le faire dans votre code de traitement: obtenez la valeur la plus élevée du champ, ajoutez-en une, puis affectez cette valeur ) ou allez dans la base de données et définissez IDENTITY _INSERT sur la table, ce qui vous permet d'attribuer temporairement des valeurs aux champs IDENTITY.

SET IDENTITY_INSERT [yourTableName] ON

--go back and run your C# code>

SET IDENTITY_INSERT [yourTableName] OFF
14
Matt Thrower

Ce qui a fonctionné pour moi était un simple EDMX update. Comme j’avais défini Identity Off avant, puis l’a modifié en automatique. Mais n'a pas mis à jour le Edmx. Après la mise à jour, cela a bien fonctionné.

4
Linet Pereira

Ce qui a fonctionné pour moi dans ce cas est de définir un attribut sur la propriété de clé primaire de la classe:

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int DepartmentId { get; set; }

IDENTITY_INSERT était déjà activé dans ma base de données.

3
steveareeno

L'incrément de votre clé étrangère dans votre table SQL est défini automatiquement ... Ainsi, lorsque vous souhaitez insérer des éléments, vous devez supprimer cette clé étrangère du code comme dans cet exemple.

Code SQL: 

CREATE TABLE [dbo].[annexe1](
[cle] [int] IDENTITY(1,1) NOT NULL,
[tarif] [nvarchar](50) NULL,
[libele] [nvarchar](max) NULL)

Code Asp.Net:

InsertCommand = "INSERT INTO [annexe6] ([cle], [tarif], [libele]) VALUES (@cle, @tarif, @libele)"

Correction:

InsertCommand = "INSERT INTO [annexe6] ([tarif], [libele]) VALUES (@tarif, @libele)"
0
Mensinovish

Ok, vous avez déjà une solution ... Mais envisagez de laisser ID en tant que clé primaire unique et Company_Id en tant que clé étrangère.

0
user2956759

Supprimer l'identité de l'ID ou ajouter 

SET IDENTITY_INSERT [dbo].[Project] ON

Normalement, l'ID est inséré sans intervention de l'utilisateur. Vous obtenez donc l'erreur car vous essayez d'y entrer des données. Si vous l'activez, vous pourrez saisir les données souhaitées OU, supprimez simplement le code contenant les données que vous saisissez dans l'ID, à moins que cela ne soit nécessaire 

0
Keii

Pouvez-vous essayer 2 choses et essayer chacune séparément?

  • Supprimer les champs de clé primaire pour ID et Company_ID
  • Prendre la colonne ID lors de la première commande
0
kemals