web-dev-qa-db-fra.com

Le code EF commence par me donner l'erreur Impossible d'insérer une valeur explicite pour la colonne d'identité dans la table 'Personnes' lorsque IDENTITY_INSERT est défini sur OFF.

J'essaie le code d'abord d'Entity Framework 4 (EF CodeFirst 0.8) et je rencontre un problème avec un modèle simple qui a une relation 1 <-> 0..1 entre Person et Profile. Voici comment ils sont définis:

public class Person
{
    public int PersonId { get; set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime? DOB { get; set; }

    public virtual Profile Profile { get; set; }
}

public class Profile
{
    public int ProfileId { get; set; }
    public int PersonId { get; set; }
    public string DisplayName { get; set; }

    public virtual Person Person { get; set; }
}

Le contexte de la base de données ressemble à ceci:

public class BodyDB : DbContext
{
    public DbSet<Person> People { get; set; }   
}

Je n'ai pas défini DbSet pour Profile parce que je considère People comme étant sa racine globale. Lorsque j'essaie d'ajouter une nouvelle Person - même sans Profile avec ce code:

public Person Add(Person newPerson)
{
    Person person = _bodyBookEntities.People.Add(newPerson);
    _bodyBookEntities.SaveChanges();
    return person;
}

Je reçois l'erreur suivante:

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

L'objet newPerson a un 0 pour la propriété PersonId lorsque j'appelle People.Add(). Les tables de base de données sont People et Profiles. PersonId est le PK de People et est une identité à incrémentation automatique. ProfileId est la PC de Profiles et est une identité à incrustation automatique. PersonId est une colonne int non null de Profiles.

Qu'est-ce que je fais mal? Je pense adhérer à toutes les conventions de EF Code First relatives aux règles de configuration.

38
Howard Pinsley

Je reçois l'erreur suivante: Impossible d'insérer une valeur explicite pour la colonne d'identité dans la table 'Personnes' lorsque IDENTITY_INSERT est défini sur OFF.

Je pense que IDENTITY_INSERT est la fonctionnalité Auto Increment qui est désactivée . Donc, vérifiez le champ PersonId dans la base de données pour voir si c'est une identité.

En outre, cela réglera peut-être aussi votre problème.

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int PersonId { get; set; }
47
Samidjo

Cela se produira si vous procédez comme suit:

  1. Créez un champ PK non-identité sur une table.
  2. Inférer le modèle d'entité à partir de cette table.
  3. Revenez en arrière et définissez l'identité de la PK sur true.

Le modèle d'entité et la base de données ne sont pas synchronisés. Le rafraîchissement du modèle le corrigera. Je devais le faire hier. 

34
Chris B. Behrens

Je n'avais pas ce problème jusqu'à ce que j'ajoute une clé composite, donc une fois que j'ai eu 2 clés primaires cela s'est produit avec EF 6.x.x 

Sur ma clé "Id" qui a Identity Specification défini sur true, j’avais besoin de add

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]

Propriétés du modèle maintenant:

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
[Key, Column("Id", Order = 1)]
public int Id { get; set; }

[Key, Column("RanGuid", Order = 2)]
public string RanGuid { get; set; }
4
Tom Stickel

Pour le bénéfice des chercheurs: j'ai eu cette erreur, mais les corrections ci-dessus ne fonctionnaient pas. C'était dû à une erreur de ma part.

Sur mes tables, j'ai une clé primaire Guid (non clusterisée) et un index int

L'erreur se produisait lors de la tentative de mise à jour du message avec les informations du blog en tant que propriété de navigation. Voir les cours ci-dessous: 

public class Blog
{
    public Guid BlogId { get; set; }

    public int BlogIndex { get; set; }

    // other stuff
}

public class Post
{
    public Guid PostId { get; set; }

    public int PostIndex { get; set; }

    // other stuff

    public Blog Blog { get; set; }
}

Le problème était que lorsque je convertissais des DTO en modèles, BlogId était en train de devenir une new Guid() (j'ai commis une erreur dans le mappage). L'erreur résultante était la même que celle détaillée dans cette question.

Pour résoudre ce problème, je devais vérifier que les données étaient correctes lors de l'insertion (ce n'était pas le cas) et corriger le changement de données incorrect (dans mon cas, le mappage endommagé).

2
HockeyJ

Voici la solution. Voir également la pièce jointe pour plus d'aide.

Accédez au fichier ".edmx" de votre modèle EF >> Ouvrez-le >> Maintenant, cliquez avec le bouton droit sur le diagramme et choisissez "Mettre à jour le modèle à partir de la base de données".

Cela résoudra le problème car vous avez attribué à PK l'identité dans votre base de données après avoir créé votre modèle EF.

aide à recréer les étapes indiquées ci-dessus

1
Taha Ali

Vous avez cette erreur dans EF6, regardé la base de données et tout se passe bien avec Identity Specification défini sur Yes J'ai ensuite supprimé les différentes migrations et procédé à une nouvelle migration à partir des modèles actuels, puis tout a commencé à fonctionner. La solution la plus rapide puisque l’application n’était pas encore opérationnelle et en cours de développement.

 enter image description here

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

1
Ogglas

Si vous utilisez EF core et l'interface fluide comme moi, j'ai constaté que l'utilitaire Scaffold-DbContext que j'ai utilisé pour créer le modèle à partir d'une base de données existante génère une ligne pour ma colonne comme celle-ci:

entity.Property(e => e.id).ValueGeneratedNever();

Après avoir modifié la base de données en ajoutant l'attribut IDENTITY à mon identifiant, j'ai dû modifier la ligne dans:

entity.Property(e => e.id).ValueGeneratedOnAdd();

autre que d'ajouter le décorateur [DatabaseGeneratedAttribute(DatabaseGeneratedOption.None), Key] au champ id de ma classe de modèle.

Je ne suis même pas sûr que ce dernier soit nécessaire. Une fois résolu avec l'ancien correctif, je n'ai pas essayé de le supprimer.

1
Emanuele Benedetti

Dans mon cas, il semble que EF n'aime pas les types de données autres que le champ d'identité INT.

J'ai eu aussi cette erreur en utilisant PK de type tinyint. Ce n'est pas que EF ne l'aime pas, il semble que, contrairement à d'autres cas, vous devez spécifier cela dans votre configuration comme ceci:

this.Property(t => t.TableID).HasColumnName("TableID").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
0
Pablo Pagues

Dans mon cas, il semble qu'EF n'aime pas d'autre type queINTchamp d'identité - le mien était unOCTET(TINYINT du côté SQL). 

Depuis que j'ai pu mettre à jour mon projet et le changer enINTsur le SQL, après avoir ré-exécuté le code d'ingénierie inverse d'abord sur VisualStudio, l'erreur a immédiatement cessé de se produire.

0
Tuco