web-dev-qa-db-de.com

EF-Code Beim ersten Fehler wird kein expliziter Wert für die Identitätsspalte in der Tabelle 'People' eingefügt, wenn IDENTITY_INSERT auf OFF gesetzt ist.

Ich probiere den Entity Framework 4 Code First (EF CodeFirst 0.8) aus und stoße auf ein Problem mit einem einfachen Modell, das eine 1 <-> 0..1-Beziehung zwischen Person und Profile aufweist. So werden sie definiert:

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

Der DB-Kontext sieht folgendermaßen aus:

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

Ich habe keine DbSet für Profile definiert, da ich People als Aggregatstamm betrachte. Wenn ich versuche, eine neue Person hinzuzufügen - sogar eine ohne Profile mit diesem Code:

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

Ich erhalte folgende Fehlermeldung:

Es kann kein expliziter Wert für die Identitätsspalte in der Tabelle 'People' eingefügt werden, wenn IDENTITY_INSERT auf OFF gesetzt ist. 

Das newPerson-Objekt hat einen 0 für die PersonId-Eigenschaft, wenn ich People.Add() aufrufe. Die Datenbanktabellen sind People und Profiles. PersonId ist der PK von People und ist eine Auto-Inkrement-Identität. ProfileId ist der PK von Profiles und ist eine Auto-Inement-Identität. PersonId ist eine nicht-null-int-Spalte von Profiles.

Was mache ich falsch? Ich denke, ich halte mich an alle Konventionen von EF Code First über Konfigurationsregeln.

38
Howard Pinsley

Ich erhalte folgende Fehlermeldung: Es kann kein expliziter Wert für die Identitätsspalte in der Tabelle 'People' eingefügt werden, wenn IDENTITY_INSERT auf OFF gesetzt ist.

Ich denke, dass IDENTITY_INSERT die Auto Increment-Funktion ist, die deaktiviert ist .. __ Überprüfen Sie also das Feld PersonId in der Datenbank, um zu sehen, ob es eine Identität ist.

Außerdem wird vielleicht auch das Problem behoben.

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

Dies wird auftreten, wenn Sie die folgenden Schritte ausführen:

  1. Erstellen Sie ein Nicht-Identitäts-PK-Feld in einer Tabelle.
  2. Schlagen Sie das Entitätsmodell aus dieser Tabelle ab.
  3. Gehen Sie zurück und setzen Sie die PK-Identität auf true.

Das Entitätsmodell und die Datenbank sind nicht synchron. Wenn Sie das Modell aktualisieren, wird es behoben. Ich musste das erst gestern machen. 

34

Wenn Sie EF Code First verwenden, müssen Sie zusätzlich zum Annotationsattribut [DatabaseGeneratedAttribute (DatabaseGeneratedOption.Identity)] zur Datei model.cs, wie andere hier vorgeschlagen haben, auch dieselbe wirksame Änderung vornehmen in den Dateien modelMap.cs (Anweisungen zum fließenden Mapping):

Wechsel von:

this.Property(t => t.id)
   .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

zu:

this.Property(t => t.id)
   .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

(Ich verwendete EF Power Tools, um die Entitätsmodelle und die Standardzuordnungsdateien zu generieren. Dann wurde eine Id-Spalte in eine Primärschlüsselspalte umgewandelt und in SQL Server auf IDENTITY gesetzt. Daher musste ich das Attribut und die Standardzuordnung aktualisieren Datei.)

Wenn Sie ihn an beiden Stellen nicht ändern, wird immer noch derselbe Fehler angezeigt.

11
MattSlay

Ich hatte dieses Problem nicht bis ich einen zusammengesetzten Schlüssel hinzugefügt habe. Wenn ich also 2 Primärschlüssel hatte, trat dies mit EF 6.x.x auf. 

Auf meinem Schlüssel "Id", für den Identity Specification auf true gesetzt war, musste add

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]

Modelleigenschaften jetzt:

[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

Ihre Situation erinnert mich an eine Situation, die ich mit EF Code First erlebe, wenn PrimaryKey und ForeignKey dieselbe Spalte sind.

Es gibt keine direkte Möglichkeit zum Aktualisieren des Modells, derselbe Effekt kann jedoch in zwei Schritten erzielt werden.

  1. Kommentieren Sie die ProfileId in der Profile-Klasse aus. Rekompilieren und aktualisieren Sie die Datenbank.
  2. Entkommentieren Sie die Profil-ID, fügen Sie DatabaseGeneratedAttribute hinzu und aktualisieren Sie die Datenbank erneut.
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None), Key]

Auf diese Weise wird die generierte ProfileId-Spalte zu Key without Identity.

3

Zum Vorteil der Suchenden: Ich habe diesen Fehler erhalten, aber die oben genannten Korrekturen funktionierten nicht. Es lag an einem Fehler meinerseits.

In meinen Tabellen habe ich einen Guid-Primärschlüssel (nicht gruppiert) und einen int-Index. 

Der Fehler ist aufgetreten, als versucht wurde, "Post" mit den "Blog" -Informationen als Navigationseigenschaft zu aktualisieren. Siehe Klassen unten: 

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

Das Problem war, dass als ich DTOs in Modelle konvertierte, die BlogId in eine new Guid() geändert wurde (ich habe einen Fehler im Mapping gemacht). Der resultierende Fehler war derselbe wie in dieser Frage beschrieben.

Um das Problem zu beheben, musste ich überprüfen, ob die Daten beim Einfügen richtig waren (dies war nicht der Fall) und die fehlerhafte Änderung der Daten korrigiert (in meinem Fall das defekte Mapping).

2
HockeyJ

Hier ist die Lösung. Weitere Informationen finden Sie im Anhang.

Navigieren Sie zu Ihrer EF-Modelldatei ".edmx" >> Öffnen Sie sie >> Klicken Sie mit der rechten Maustaste auf das Diagramm und wählen Sie "Modell aus Datenbank aktualisieren".

Dies wird behoben, da Sie nach dem Erstellen Ihres EF-Modells PK zur Identität in Ihrer Datenbank gemacht haben.

Hilfe zum Wiederherstellen der oben genannten Schritte

1
Taha Ali

Ich habe diesen Fehler in EF6 gesehen, die Datenbank angesehen und alles mit Identity Specification auf Yes gesetzt. Ich entfernte dann die verschiedenen Migrationen und machte eine neue Migration aus den aktuellen Modellen, und dann begann alles zu funktionieren. Schnellste Lösung, da die Anwendung noch nicht live war und sich noch in der Entwicklung befindet.

 enter image description here

In Tabelle .__ kann kein expliziter Wert für die Identitätsspalte eingefügt werden. 'Test', wenn IDENTITY_INSERT auf OFF gesetzt ist.

1
Ogglas

Wenn Sie EF Core und die fließende Schnittstelle wie ich verwenden, habe ich festgestellt, dass das Dienstprogramm Scaffold-DbContext, mit dem ich das Modell aus einer vorhandenen Datenbank erstellt habe, eine Zeile für eine solche Spalte generiert:

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

Nachdem ich die Datenbank geändert habe und das IDENTITY-Attribut meiner ID hinzugefügt habe, musste ich die Zeile ändern in:

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

anders als das Hinzufügen des Dekorators [DatabaseGeneratedAttribute(DatabaseGeneratedOption.None), Key] zum ID-Feld in meiner Modellklasse.

Ich bin mir nicht einmal sicher, ob Letzteres notwendig ist. Nachdem ich den vorherigen Fix behoben hatte, habe ich nicht versucht, ihn zu entfernen.

1

In meinem Fall scheint es, dass EF keinen anderen Typ als das INT-Identitätsfeld mag - mein Name war ein BYTE (TINYINT auf der SQL-Seite).

Ich hatte auch diesen Fehler bei der Verwendung von PK vom Typ tinyint. Es ist nicht so, dass EF es nicht mag, es scheint, dass Sie, anders als in anderen Fällen, dies in Ihrer Konfiguration wie folgt angeben müssen:

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

In meinem Fall scheint es, dass EF keinen anderen Typ als INT - Identitätsfeld mag - mein Name war ein BYTE (TINYINT auf der SQL-Seite). 

Da ich mein Projekt aktualisieren und in SQL in INT ändern konnte, trat der Fehler nach erneutem Ausführen des Reverse Engineering Code First auf VisualStudio sofort auf.

0
Tuco