2013-07-11 18 views
6

Ich habe ein erstes EF5-Code-Projekt, das das Attribut [DatabaseGenerated (DatabaseGeneratedOption.Computed)] verwendet. Diese Option überschreibt meine Einstellungen.Entity Framework 5: Verwenden von DatabaseGeneratedOption.Computed Option

Betrachten Sie diese SQL-Tabelle:

CREATE TABLE Vehicle (
    VehicleId int identity(1,1) not null, 
    Name varchar(100) not null default ('Not Set') 
) 

ich die SQL-Standard-Konstrukt bin mit der [Name] ist zu setzen, falls es nicht gesetzt.

In Code hinter, ich habe eine Klasse ähnlich definiert:

public class Vehicle { 
    ... 

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)] 
    public string ShoulderYN { get; set; } 
} 

Wenn ich die Einheit in Code aktualisieren, stellen Sie den Wert in der Standardeinstellung überschreibt meine neue Einstellung.

In Code, habe ich (pseudo):

vehicle.Name = 'Update Name of Vehicle'; 
_dbContext.Update(vehicle); 
_dbContext.SaveChanges(); 

Das erwartete Ergebnis ist Vehicle.Name = 'Update Name des Fahrzeugs'.

Das tatsächliche Ergebnis ist Vehicle.Name = 'Nicht festgelegt'.

Gibt es eine Möglichkeit in EF5 zu sagen: "Wenn Vehicle.Name null/leer ist, verwende den in der Datenbank definierten Wert? Anderenfalls, wenn ich den Wert im Code festlege, möchte ich diesen Wert verwenden."

Danke.

Steve

Antwort

9

Offenbar, nein gibt es nicht. Es ist nicht so intelligent :)

Wie Sie vielleicht bereits lesen, teilt Computed Option nur der EF, um Ihre Spalte nicht zu aktualisieren, weil Sie einen Wert auf der DB-Seite selbst berechnen. EF wird dann einfach den neu berechneten Wert aus Ihrer Datenbank zurückgeben (was in Ihrem Fall "Nicht gesetzt" ist).

Ihre grundlegende drei Optionen sind - wie pro EF Quellcode-Dokumentation:

  • Keine - Die Datenbank keine Werte erzeugen.
  • Identität - Die Datenbank generiert einen Wert, wenn eine Zeile eingefügt wird.
  • Berechnet - Die Datenbank generiert einen Wert, wenn eine Zeile eingefügt oder aktualisiert wird.

https://github.com/aspnet/EntityFramework6/blob/527ae18fe23f7649712e9461de0c90ed67c3dca9/src/EntityFramework/DataAnnotations/Schema/DatabaseGeneratedOption.cs

Da Sie ein wenig mehr benutzerdefinierte Logik erwarten zu tun, ich fürchte, Sie es selbst tun müssten. Ich würde vorschlagen, dass Sie aufhören, sich auf die Datenbank-Standardbeschränkung zu verlassen, und alles im Code zuerst machen. Auf diese Weise würden Sie einen Code so haben:

public class Vehicle 
{ 
    public Vehicle() 
    { 
    this.Name = "Not set"; 
    } 

    // Without 'Generated' attribute 
    public string Name { get; set; } 
} 

diese Weise, wenn Ihr Entity erstellt wird, startet es automatisch mit den erwarteten Standardwert. Und kann später geändert werden, indem einfach die Eigenschaft Name geändert wird.

Hoffe es hilft!

0

Ich habe dies für Stunden überprüft, um eine gute Antwort zu bekommen, aber nein: EF kann Modelle nicht durch automatisch generierte ID aktualisieren.

Sie haben 3 Optionen:

  1. andere VehicleID zu Fahrzeugmodell hinzufügen.
  2. Ändern Sie die automatisch generierte ID so, dass sie manuell von Ihnen generiert wird.
  3. Einstellung der eindeutigen Kennung als etwas anderes als die generierte ID in Ihrem Modell. In Ihrer Fahrzeugklasse kann dies die Name-Eigenschaft sein.

Ich schlage vor, Option 3: Einrichten der eindeutigen ID zu Vehicle.Name (und Sie können weitere Eigenschaften hinzufügen). Dann: wenn das Fahrzeug durch eindeutige ID nicht existiert, fügen Sie neues Fahrzeug zu db-Kontext:

//if there is no such a Vehicle in system, add it: 
if (vehicle.Name !=null && vehicle.Name != String.Empty && _dbContext.Where(v => v.Name == vehicle.Name).FirstOrDefault() == null) 
    _dbContext.Add(vehicle); 

_dbContext.SaveChanges(); 
0

Eigentlich ist es eine einfache Lösung dafür:

  • Sie müssen standardmäßig verlassen constraint mit dem Wert in der Schöpfung Skript Tabelle, wie es jetzt ist:

    CREATE TABLE Vehicle (
        VehicleId int identity(1,1) not null, 
        Name varchar(100) not null default ('Not Set') 
    ) 
    
  • Gerade DatabaseGenerated Attribut von Immobilien in Klassendefinition entfernen:

    public class Vehicle { 
        ... 
    
        [DatabaseGenerated(DatabaseGeneratedOption.Computed)] 
        public string ShoulderYN { get; set; } 
    } 
    

Und das ist es: nun Datenbank wird nur Standardwert verwenden, wenn Sie nicht einen gewissen Wert in Code angeben. Hoffe das hilft.

+0

Warum wird dieses Verhalten nicht standardmäßig bereitgestellt? Was ist der Vorteil dahinter? Zum Beispiel bestimme ich das Standarddatum (notnull) in einer Spalte der Tabelle in DB. Aber EF senden eine min Datetime wenn kein Wert per Code gesendet wird. Ich kann wirklich keine Logik darin finden. –

Verwandte Themen