none
Entity Framework - Id automatisch inkrementieren RRS feed

  • Frage

  • Hallo Leute,

    ich habe eine Tabelle Table (sollen Daten für meine Tische, sprich graphische Rechtecke darstellen) mit einer eindeutigen ID (integer). Nun möchte ich mit meinem selbst programmierten Editor die Daten meiner Erstellten Rechtecke in diese Tabelle speichern. Das Problem dabei ist, dass die ID nicht automatisch inkrementiert wird. Jedoch habe ich (ich bin zumindest davon überzeugt) mit dem EF-Designer und dem DB-Designer alles richtig eingestellt. Ich zeige euch einfach mal ein paar Bilder, die meine Vorgehensweise dokumentieren:

    Hier das Bild des Datenbank-Designer:

    Hier das Bild des EF-Designers:

    Die Fehlermeldung bei dieser Einstellung lautet:

    "Ein expliziter Wert für die Identitätsspalte kann nicht in der 'Tables'-Tabelle eingefügt werden, wenn IDENTITY_INSERT auf OFF festgelegt ist."	
    System.Exception {System.Data.SqlClient.SqlException}
    

    Aber das sollten doch die korrekten Einstellungen sein? Oder habe ich irgendetwas vergessen?

    Grüße,

    GreenPepper_v_1.0

    Samstag, 2. April 2011 09:01

Antworten

  • Hallo G.,

    Du hast meine Frage nicht beantwortet. -> "was für ein Quellcode führt denn zu der Ausnahme?" (möglichst reproduzierbar)

    für die Basics ... ich gehe mal von SQL Server 2008 R2 / Visual Studio 2010 / .NET 4.0 aus. [...] Bitte gewährleiste zumindest das aktuelle Servicepack Deiner genutzten SQL-Server-Version.

    Ein Identity_Insert auf ON brauchst Du hier normal nicht, denn die Werte werden ja automatisch berechnet. Im Gegenteil, würdest Du versuchen, diesen Wert selber zu schreiben (oder zum Beispiel ein Trigger würde dies veranlassen), so kann das zur angegebenen Meldung kommen können - ein normales Setzen der ID würde allerdings auch ignoriert und letztlich die ID vom Server benutzt. Du brauchst Dich bei korrekter Einbindung des EF Modelles darum eigentlich (normal) nicht zu kümmern.

    Hmm, hier haben wir eigentlich eher eine C# Gruppe, und das ist jetzt eher DB-technisches ... ok - , ein paar Grundlagen trotzdem. Also normal braucht man im 'SQL Server Management  Studio' nur mit der rechte Maus auf die Tabelle zu gehen, [Entwerfen], ID-Spalte markieren, und bei Identitätsspezifikation/Aufklappen und bei '(Ist Identity)' doppelklicken - dadurch ergibt sich das Bild, was Du ja aber auch so hast gemäß Deines Bildes. Entscheidend ist letztlich, wie das Scirpt zur Erstellung aussieht ... -> RMaus auf Tabelle / 'Script für Tabelle als' / 'Neues Editor Abfragefenster'.
    Da müsste dann (u.a.) normal etwas wie folgendes stehen:

        CREATE TABLE [dbo].[Table](
    	   [ID] [int] IDENTITY(1,1) NOT NULL,
           -- und entsprechend weitere ...
    

    [IDENTITY-Eigenschaft (Transact-SQL)]
    http://msdn.microsoft.com/de-de/library/ms186775.aspx
    _________________

    Ansonsten kann man natürlich mal testen, was bei folgender Aktion herauskommt:
    RechteMaus auf Datenbank/ Neue Abfrage:

    IF OBJECT_ID ('dbo.TableNeu', 'U') IS NOT NULL
      DROP TABLE [dbo].[TableNeu];
    GO
    CREATE TABLE [dbo].[TableNeu]
    (
      ID int IDENTITY(1,1), Vorname varchar (20),
      Nachname varchar(30), Kennzeichen char(1)
      CONSTRAINT [PK_TableNeu] PRIMARY KEY CLUSTERED( [ID] ASC)
    );
    
    INSERT [dbo].[TableNeu](Vorname, Nachname, Kennzeichen)
    VALUES ('Karin', 'Schmidt', 'F');
    
    INSERT [dbo].[TableNeu] (Vorname, Nachname, Kennzeichen)
    VALUES ('Peter', 'Kahn', 'O');
    
    Select * FROM [dbo].[TableNeu]
    -- da müssten dann zwei Sätze (Karin,Peter) mit ID 1 und 2 sein.
    


    dann im C#-Projekt mal entsprechend das ADO.NET Entity DataModel aus DB generieren und folgenden Code ausführen:

          DeineEntities db = new DeineEntities();
          TableNeu t = new TableNeu();
          t.Vorname = "HerbertNeu";
          db.AddToTableNeu(t); db.SaveChanges();
    

    funktioniert das?

    Ich denke - Du hattest halt nur ein Aktualisierungsproblem - und das ist behoben.


    ciao Frank
    • Als Antwort vorgeschlagen Pawel Warmuth Montag, 4. April 2011 06:32
    • Als Antwort markiert DevPepper Montag, 4. April 2011 12:30
    Sonntag, 3. April 2011 08:43

Alle Antworten

  • Hallo G.,

    Ist in Deinem EDMX im SSDL-Content denn wirklich für diese Tabelle(n) folgendes enthalten:  StoreGeneratedPattern="Identity"    ?
    Also gemäß Deines Eigenschaften-Fensters sieht es ja so korrekt aus, auch die DB-Einstellungen.
    Infos auch bei: [SET IDENTITY_INSERT (Transact-SQL)]

    Wichtig: was für ein Quellcode führt denn zu der Ausnahme?

    Hier mal ein Beispiel:

          DeineEntities db = new DeineEntities();
          Table t = new Table();
          t.Name = "NameNeu"; 
          db.AddToTable(t); db.SaveChanges();
    

    somit müsste eigentlich Deine ID über die DB autogeneriert werden.

     


    ciao Frank
    • Als Antwort vorgeschlagen Pawel Warmuth Montag, 4. April 2011 06:32
    Samstag, 2. April 2011 10:52
  • Es lag tatsächlich daran, dass das EF-Modell noch nicht richtig aktualisiert wurde. Ich habe allerdings noch eine Frage: Wie kann ich denn jetzt die ID explizit ändern? Kann ich das bequem über den Designer machen, oder muss ich die XML-Dateien manuell bearbeiten. Wenn letzteres der Fall wäre, hätte ich ein Problem, da ich mich mit den Konfigurationen per XML schlecht auskenne.

    EDIT: Was ist, wenn man der ID nicht mehr den automatisches INCREMENT Wert geben möchte, sondern einen Expliziten?
    • Bearbeitet DevPepper Samstag, 2. April 2011 16:16
    Samstag, 2. April 2011 15:33
  • Hallo G.,

    • Es lag tatsächlich daran, dass das EF-Modell noch nicht richtig aktualisiert wurde.

    freut mich, dass es dann jetzt bei Dir klappt.

     

    • Wie kann ich denn jetzt die ID explizit ändern?

    Käme darauf an, was genau Du an der ID ändern willst. Metadaten, Namen, Eigenschaften, und auf welcher schematischen Ebene?
    Das Datenspeicherschema (SSDL) kannst Du ja über "Rechte Maus / aus Datenbank aktualisieren" im EDMX-Designer automatisch erneuern/korrigieren.
    Das konzeptionelle Modell (CSDL) ändert sich dann ggf. nicht, aber das kannst es über den Entity Data Model-Designer (Entity Designer) in den Eigenschaften, die schon in Deinen Bilder sichtbar sind ändern.
    Selbst das Ändern im XML ist aber nicht so schwer, .... man kann hier wegen der Schema-Zuordnung die Tastenfolge Strg-J auf "Identity" machen, sodass er Vorschläge für die Ersetzung macht. Die XML-Datei kann man zum Beispiel mit RechteMaus auf die EDMX -> ÖffnenMit/Xml(Text)Editor  ansehen und bearbeiten.


    ciao Frank
    • Als Antwort vorgeschlagen Pawel Warmuth Montag, 4. April 2011 06:32
    Samstag, 2. April 2011 16:04
  • Hm ich habe mir gerade das hier durchgelesen:

    http://msdn.microsoft.com/en-us/library/aa259221%28v=sql.80%29.aspx

    Aber wie konfiguriere ich jetzt meine DB, dass sie automatisch Identy_Insert auf On stellt?


    Samstag, 2. April 2011 16:11
  • Hallo G.,

    Du hast meine Frage nicht beantwortet. -> "was für ein Quellcode führt denn zu der Ausnahme?" (möglichst reproduzierbar)

    für die Basics ... ich gehe mal von SQL Server 2008 R2 / Visual Studio 2010 / .NET 4.0 aus. [...] Bitte gewährleiste zumindest das aktuelle Servicepack Deiner genutzten SQL-Server-Version.

    Ein Identity_Insert auf ON brauchst Du hier normal nicht, denn die Werte werden ja automatisch berechnet. Im Gegenteil, würdest Du versuchen, diesen Wert selber zu schreiben (oder zum Beispiel ein Trigger würde dies veranlassen), so kann das zur angegebenen Meldung kommen können - ein normales Setzen der ID würde allerdings auch ignoriert und letztlich die ID vom Server benutzt. Du brauchst Dich bei korrekter Einbindung des EF Modelles darum eigentlich (normal) nicht zu kümmern.

    Hmm, hier haben wir eigentlich eher eine C# Gruppe, und das ist jetzt eher DB-technisches ... ok - , ein paar Grundlagen trotzdem. Also normal braucht man im 'SQL Server Management  Studio' nur mit der rechte Maus auf die Tabelle zu gehen, [Entwerfen], ID-Spalte markieren, und bei Identitätsspezifikation/Aufklappen und bei '(Ist Identity)' doppelklicken - dadurch ergibt sich das Bild, was Du ja aber auch so hast gemäß Deines Bildes. Entscheidend ist letztlich, wie das Scirpt zur Erstellung aussieht ... -> RMaus auf Tabelle / 'Script für Tabelle als' / 'Neues Editor Abfragefenster'.
    Da müsste dann (u.a.) normal etwas wie folgendes stehen:

        CREATE TABLE [dbo].[Table](
    	   [ID] [int] IDENTITY(1,1) NOT NULL,
           -- und entsprechend weitere ...
    

    [IDENTITY-Eigenschaft (Transact-SQL)]
    http://msdn.microsoft.com/de-de/library/ms186775.aspx
    _________________

    Ansonsten kann man natürlich mal testen, was bei folgender Aktion herauskommt:
    RechteMaus auf Datenbank/ Neue Abfrage:

    IF OBJECT_ID ('dbo.TableNeu', 'U') IS NOT NULL
      DROP TABLE [dbo].[TableNeu];
    GO
    CREATE TABLE [dbo].[TableNeu]
    (
      ID int IDENTITY(1,1), Vorname varchar (20),
      Nachname varchar(30), Kennzeichen char(1)
      CONSTRAINT [PK_TableNeu] PRIMARY KEY CLUSTERED( [ID] ASC)
    );
    
    INSERT [dbo].[TableNeu](Vorname, Nachname, Kennzeichen)
    VALUES ('Karin', 'Schmidt', 'F');
    
    INSERT [dbo].[TableNeu] (Vorname, Nachname, Kennzeichen)
    VALUES ('Peter', 'Kahn', 'O');
    
    Select * FROM [dbo].[TableNeu]
    -- da müssten dann zwei Sätze (Karin,Peter) mit ID 1 und 2 sein.
    


    dann im C#-Projekt mal entsprechend das ADO.NET Entity DataModel aus DB generieren und folgenden Code ausführen:

          DeineEntities db = new DeineEntities();
          TableNeu t = new TableNeu();
          t.Vorname = "HerbertNeu";
          db.AddToTableNeu(t); db.SaveChanges();
    

    funktioniert das?

    Ich denke - Du hattest halt nur ein Aktualisierungsproblem - und das ist behoben.


    ciao Frank
    • Als Antwort vorgeschlagen Pawel Warmuth Montag, 4. April 2011 06:32
    • Als Antwort markiert DevPepper Montag, 4. April 2011 12:30
    Sonntag, 3. April 2011 08:43
  • Ja danke, jetzt geht alles wunderbar!

    Jetzt nochmal zu deiner Frage:was für ein Quellcode führt denn zu der Ausnahme?"

    Genau dieser Code hier hatte zu einem fehler geführt:

    private void AddArticleExecute( object parameter )
        {
          Article tempArticle = new Article
          {
            Id = g_iPseudoWert, /* explizieter int-Wert */
            Name = string.Empty,
            Description = string.Empty,
            ArticleNr = 0,
            Category = Model,
            Price = 0.0m,        
          };
          try
          {
            tempArticle.ArticleNr = Articles.Max( p => p.ArticleNr ) + 1;
          }
          catch
          {
            tempArticle.ArticleNr = 1;
          }
    
          Save(); // Hier (Bei db.SaveChanges() trat der Fehler auf
    
          ArticleViewModel newArticle = new ArticleViewModel( tempArticle, this );
          Articles.Add( newArticle );      
        }
    

    Montag, 4. April 2011 12:34