2014-10-14 2 views
5

Ich gehe von einem vorhandenen Modell und einer Datenbank zu Entity Framework. In dieser Datenbank gibt es mehrere Tabellen mit GUID-Spalten, die keine Primärschlüssel (oder Schlüssel überhaupt) sind. Jede Tabelle hat eine ID-Spalte. In den GUID-Spalten ist die ROWGUIDCOL-Eigenschaft sowie eine DEFAULT (newid()) definiert.Automatisch generierte GUID-Spalte, die kein Primärschlüssel in Entity Framework ist

Jetzt, wenn ich in den DB einfügen, bekomme ich alle Nullen für diese Spalte.

Ich habe versucht, Daten Anmerkungen mit:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
public Guid Guid {get; set;} 

Das Problem dabei ist, dass es die Identität Eigenschaft auf meine ID-Spalte fällt (und gibt mir Fehler einfügen). Darüber hinaus bemerkte ich, dass die folgende Migration, EF erzeugt tatsächlich identisch SQL sowohl für die nach oben und unten Methoden:

public override void Up() 
{ 

    AlterColumn("dbo.Client", "Guid", c => c.Guid(nullable: false, identity: true)); 
} 

public override void Down() 
{ 
    AlterColumn("dbo.Client", "Guid", c => c.Guid(nullable: false)); 
} 

Mit dem generierten SQL aus:

ALTER TABLE [dbo].[Client] ALTER COLUMN [Guid] [uniqueidentifier] NOT NULL 

Warum die obige Migration erstellen die gleiche SQL für beide Aussagen? Wie bekomme ich EF zum Generieren von GUIDs? Kann/muss ich das im Client (Code) Space machen? Wenn ich muss, wie kann ich Einzigartigkeit über Tabellen garantieren?

+0

Ich weiß nicht EF, aber es scheint, dass Sie Identität Eigenschaft und Standardwert verwirren. Ein GUID-Datentyp kann die Eigenschaft "identity" in SQL Server nicht haben – jazzytomato

+0

Ist Ihr Primärschlüssel mit dem Attribut [Key] versehen? – Keith

+1

DatabaseGenerationOption.Identity sollte für Identitätsspalte verwendet werden. Haben Sie DatabaseGenerationOption.Computed stattdessen versucht? Es sollte verhindern, dass EF einen Wert sendet, wenn die Spalte eingefügt wird, und es sollte den db-generierten Wert richtig auf SaveChanges ziehen – ESG

Antwort

2

DatabaseGenerationOption.Identity sollte für Identitätsspalte verwendet werden.

Verwenden Sie stattdessen DatabaseGenerationOption.Computed. Es sollte verhindern, dass EF beim Einfügen der Spalte einen Wert sendet, und es sollte den db-generierten Wert bei SaveChanges korrekt abrufen.

+0

gibt es nicht eine Möglichkeit, dies in der DB zuerst zu tun, und EF erbt (automatisch erstellt) diese Einstellung in die Poco Klasse, anstatt Annotation manuell zu setzen? – batmaci

+0

Ich bin mit db nicht besonders vertraut, aber ich wäre überrascht, wenn es so wäre. – ESG

1

Ich hatte einige Fehler bekommen, als ich vorbestehende ID-ID-Spalten in GUIDs konvertieren wollte. Berechnet würde nicht funktionieren, Einstellung als Identität würde nicht funktionieren. Die Einstellung von DatabaseGeneratedOption.None würde zu Fehlern führen, da ich keine Nullen in das erforderliche Feld einfügen konnte. Ich hatte eine neue Generation in meinem Konstruktor, aber das schien auch nicht zu helfen.

Um es zum Laufen zu bringen, löschte ich meine .cs-Dateien und meine Datenbank. Dann konnte ich mit Dataannotations das System besiegen, indem ich die neue GUID-ID auf Key, DatabaseGeneratedOption.None setzte und dann ein Backing-Feld setzte hinter der ID-Eigenschaft. Das zwang meinen Getter, das private Feld zu betrachten, festzustellen, ob es Guid.Empty war, und wenn ja, um eine neue GUID für mich zu generieren.

private Guid id = Guid.Empty; 

    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)] 
    [HiddenInput(DisplayValue = false)] 
    public Guid CompanyId 
    { 
     get 
     { 
      if(id==Guid.Empty) 
       id = new Guid(); 
      return id; 
     } 
     set { id = value; } 
    } 
Verwandte Themen