2010-06-10 4 views
15

Ich möchte durch eine Sammlung von Objekten Schleife und fügen Sie sie alle an einen Tisch. Die Zieltabelle hat ein Auto-Inkrement-Feld. Wenn ich ein einzelnes Objekt hinzufüge, gibt es kein Problem. Wenn ich zwei Objekte mit dem Primärschlüssel von Null hinzufüge, schlägt das Entitätsframework fehl. Ich kann Primärschlüssel manuell spezifizieren, aber der Hauptpunkt, den EF zu versuchen, war, das Leben leichter zu machen, nicht komplizierter. Hier ist der Code und die empfangene Ausnahme folgt.Automatische Nummerierung mit Entity Framework

foreach (Contact contact in contacts) 
{    
    Instructor instructor = InstructorFromContact(contact);    
    context.AddToInstructors(instructor);    
} 

try 
{     
    context.SaveChanges();     
} 
catch (Exception ex) 
{ 
    Console.WriteLine(ex.ToString()); 
} 

Der Fehler ist:

System.InvalidOperationException: Die Änderungen an der Datenbank erfolgreich begangen wurden, aber ein Fehler aufgetreten ist, während das Kontext Objekt zu aktualisieren. Der ObjectContext befindet sich möglicherweise in einem inkonsistenten Zustand. Inner Ausnahmemeldung: AcceptChanges kann nicht fortgesetzt werden, weil das Schlüsselwerte Konflikt des Objekts mit einem anderen Objekt in dem Object. Stellen Sie sicher, dass die Schlüsselwerte eindeutig sind, bevor Sie AcceptChanges aufrufen. bei System.Data.Objects.ObjectContext.SaveChanges (Saveoptions-Optionen)
bei System.Data.Objects.ObjectContext.SaveChanges() bei DataMigration.Program.CopyInstructors() in C: \ Projects \ Datenmigration \ Program.cs : line 52

+3

ich vermute, dass, wenn Sie nur das Autowert-Feld leer lassen, wird die Datenbank für Sie zuweisen, wenn Sie zu begehen. –

+0

Ja, es funktioniert, fügt die Datensätze hinzu und weist Primärschlüssel zu Das Problem ist, dass ich für ein solches typisches Szenario keine Ausnahme bekommen sollte. Ich bin sicher, dass es eine 'richtige' Art und Weise gibt, dies innerhalb des Rahmens zu tun, nur nicht sicher wie. – dcompiled

+0

Nun, die Ausnahme wurde gestoppt, nachdem ich verschiedene Änderungen an der Tabelle vorgenommen und das Modell aktualisiert habe. Nicht sicher, was den Unterschied ausgemacht hat. Die einzigen Änderungen, die ich vorgenommen habe, waren einige Standardwerte für Spalten hinzuzufügen und diese Spalten auf null zu setzen. Nicht überzeugt davon, dass sich die Änderungen auf die Ausnahme beziehen. – dcompiled

Antwort

18

Setzen Sie das Attribut StoreGeneratedPattern in Ihrem SSDL für das Feld autoincrement auf "Identity". Es sollte helfen.

+7

Beachten Sie, dass Sie diese Eigenschaft nicht einfach im Designer festlegen können. Sie müssen den SSDL-Abschnitt manuell bearbeiten. Ich las diese Antwort durch und dachte: "Ich habe das schon gemacht.", Und ich schaute weiter, ich konnte Stunden sparen, indem ich die * SSDL * bemerkte Dies ist ein bekannter Fehler im Designer. http://geeksharp.com/2010/05/27/ef4-bug-in-storegeneratedpattern-ssdl/ und http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/404d3017-01b7 -4129-8e05-f4aa48f15f08 – DanO

+0

Sie möchten vielleicht auf diese einwägen: http://meta.stackexchange.com/questions/82509/should-accounts-used-by-multiple-users-be-allowed/82519#82519 – smartcaveman

+0

@Devart dies, löste nicht für mich .. – Campinho

12

Dies geschieht, weil trotz des automatisch generierten Wert der Spalte in der Datenbank die EF erstellt wurde nie darüber wußte.

Um EF mitzuteilen, dass die Datenbank den generierten Wert verarbeiten soll, müssen Sie Ihre edmx-Datei öffnen (dazu verwende ich immer den XML-Editor von VS) und in der Speicherschema-Definitionssprache (SSDL) Bereich, fügen Sie das Attribut StoreGeneratedPattern = „Identität“ auf die Spalte, die das erzeugte Muster benötigt. Auf diese Weise liest EF den im DB erzeugten Wert und speichert ihn im Speichercache.

Ihre Entitätstyp-Definition mehr aussehen oder weniger wie folgt aus:

<EntityType Name="INVOICE"> 
      <Key> 
      <PropertyRef Name="CODE" /> 
      </Key> 
      <Property Name="CODE" Type="varchar" Nullable="false" 
       MaxLength="10" StoreGeneratedPattern="Identity"/>     
</EntityType> 

Beachten Sie, dass, wenn Sie Ihr Modell all diese Änderungen verloren gehen passieren zu aktualisieren, und Sie werden alle den gesamten Prozess wiederholen .

1.0 Dies funktioniert für EF, bin ich, wenn nicht sicher, in EF4 all diese Probleme bereits behoben werden.

+2

Ich denke, wo ich falsch ging ist, dass ich zunächst das Modell aus der Datenbank erstellt und vergessen habe, das Auto-Nummer-Feld zu setzen. LaterIch habe meine Datenbank bearbeitet und diese Eigenschaft gefolgt vom Befehl "update model from database" in Visual Studio 2010 eingestellt. Die Update-Funktion scheint neue Eigenschaften hinzuzufügen, ist aber nicht genau sicher, ob sie vorhandene modifizierte Eigenschaften korrekt "behebt". Durch das Löschen meines Modells und die Neugenerierung funktionierte die automatische Nummerierung wie erwartet. Hätte ich es jedoch besser gewusst, hätte ich Ihre Idee ausprobiert. – dcompiled

+0

Derzeit (aber hoffentlich bald!) Ich benutze nicht EF4, aber ich lese etwas auf dieser Seite, die darüber spricht: http://geeksharp.com/2010/05/27/ef4-bug-in-storegeneratedpattern-ssdl/ – cepriego

+2

Microsoft stellt hier einen Hotfix für VS2010SP1 bereit. http://connect.microsoft.com/VisualStudio/Downloads/DownloadDetails.aspx?DownloadID=37957 Es scheint für mich zu arbeiten. – kimsk

2

ich EF6 bin mit den StoreGeneratedPattern zu setzen, können Sie auch offene EDMX-Datei in Visual Studio versuchen, direkt an der Spalte in der Tabelle Daten klicken und wählen Sie Eigenschaften,

Dann können Sie es von None auf Identity in Eigenschaftsfenster: