2013-07-11 4 views
6

Mam pierwszy projekt kodu EF5, który używa atrybutu [DatabaseGenerated (DatabaseGeneratedOption.Computed)]. Ta opcja przesłania moje ustawienia.Entity Framework 5: Using DatabaseGeneratedOption.Computed opcja

Rozważmy tę tabelę SQL:

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

używam domyślnego SQL konstrukt ustawienie [Nazwa] to sprawa nie jest ustawiony.

W kodzie tyłu, Mam klasy zdefiniowane podobne do:

public class Vehicle { 
    ... 

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

Kiedy zaktualizować podmiot w kodzie, wartość ustawiona w domyślnej zastępuje moje nowe ustawienie.

W kodzie mam (pseudo):

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

Oczekiwany wynik to Vehicle.Name = 'Aktualizacja Nazwa pojazdu.

Rzeczywistym wynikiem jest Vehicle.Name = "Not Set".

Czy istnieje sposób w EF5, aby powiedzieć "jeśli nazwa pojazdu jest pusta/pusty, użyj wartości zdefiniowanej w bazie danych? W przeciwnym razie, jeśli ustawię wartość w kodzie, chcę użyć tej wartości."

Dzięki.

Steve

Odpowiedz

9

Najwyraźniej nie ma. To nie jest takie mądre :)

Jak już możesz przeczytać, opcja Obliczona po prostu mówi EF, aby nie aktualizował twojej kolumny, ponieważ obliczasz wartość po stronie DB samemu. EF następnie zwróci nowo wyliczoną wartość z bazy danych (w twoim przypadku "Nie ustawiono").

swoje podstawowe trzy opcje są - jak na EF dokumentacji kodu źródłowego:

  • Brak - Baza nie generuje wartości.
  • Tożsamość - Baza danych generuje wartość po wstawieniu wiersza.
  • Obliczone - baza danych generuje wartość po wstawieniu lub zaktualizowaniu wiersza.

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

Ponieważ można się spodziewać nieco bardziej niestandardowe logika należy zrobić, obawiam się, że trzeba to zrobić samemu. Proponuję przestać polegać na domyślnym ograniczeniu bazy danych i zrobić wszystko w pierwszym podejściu kodu. W ten sposób otrzymasz następujący kod:

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

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

W ten sposób, po utworzeniu twojego Entity, automatycznie zaczyna się od oczekiwanej wartości domyślnej. I może być później zmieniony po prostu modyfikując właściwość Nazwa.

Mam nadzieję, że pomoże!

0

Sprawdziłem to przez wiele godzin, aby uzyskać dobrą odpowiedź, ale nie: EF nie może aktualizować modeli przez automatyczne generowanie identyfikatorów.

Masz 3 opcje:

  1. Dodanie kolejnego VehicleId do modelu pojazdu.
  2. Zmień automatycznie wygenerowany identyfikator, aby był generowany ręcznie.
  3. Ustawienie unikalnego identyfikatora na coś innego niż wygenerowany identyfikator w modelu . W swojej klasie pojazdów może to być właściwość Nazwa.

Proponuję opcję 3: Ustawienie identyfikatora unikalnego na Vehicle.Name (i można dodać więcej właściwości). Następnie: jeśli pojazd o unikalnej-id nie istnieje, dodać nowy pojazd do db-context:

//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

Właściwie istnieje proste rozwiązanie tego problemu:

  • Trzeba zostawić domyślne z ograniczeniem wartości w skrypcie tworzenia tabeli, jak jest teraz:

    CREATE TABLE Vehicle (
        VehicleId int identity(1,1) not null, 
        Name varchar(100) not null default ('Not Set') 
    ) 
    
  • Wystarczy usunąć atrybut DatabaseGenerated od nieruchomości w definicji klasy:

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

I to: teraz bazie użyje domyślną wartość tylko wtedy, gdy nie określają pewną wartość w kodzie. Mam nadzieję że to pomoże.

+0

Dlaczego to zachowanie nie jest dostarczane domyślnie? Jakie są tego korzyści? Na przykład ustalam domyślną datę (notnull) w kolumnie tabeli w DB. Ale EF wysyła min-datetime, jeśli żadna wartość nie jest wysyłana przez kod. Naprawdę nie mogę znaleźć w tym żadnej logiki. –