2011-01-13 10 views
35

Próbuję kodu Entity Framework 4's First (EF CodeFirst 0.8) i mam problem z prostym modelem, który ma relację 1 < -> 0..1, między Person i Profile. Oto w jaki sposób są one zdefiniowane:Kod EF Najpierw daje mi błąd Nie można wstawić jawnej wartości dla kolumny tożsamości w tabeli "Ludzie", gdy IDENTITY_INSERT jest ustawione na WYŁ.

public class Person 
{ 
    public int PersonId { get; set; } 

    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public DateTime? DOB { get; set; } 

    public virtual Profile Profile { get; set; } 
} 

public class Profile 
{ 
    public int ProfileId { get; set; } 
    public int PersonId { get; set; } 
    public string DisplayName { get; set; } 

    public virtual Person Person { get; set; } 
} 

Kontekst DB wygląda następująco:

public class BodyDB : DbContext 
{ 
    public DbSet<Person> People { get; set; } 
} 

nie definiują DbSet dla Profile ponieważ uważam People być jej łączna korzeń. Gdy próbuję dodać nowy Person - nawet jeden bez Profile z tym kodem:

public Person Add(Person newPerson) 
{ 
    Person person = _bodyBookEntities.People.Add(newPerson); 
    _bodyBookEntities.SaveChanges(); 
    return person; 
} 

pojawia się następujący błąd:

Cannot insert explicit value for identity column in table 'People' when IDENTITY_INSERT is set to OFF.

Przedmiotem newPerson ma 0 dla właściwości PersonId kiedy zadzwoń pod numer People.Add(). Tabele bazy danych to People i Profiles. PersonId to PK od People i jest to samo-przyrostowe Tożsamość. ProfileId to PK od Profiles i jest tożsamość samozwańcza. PersonId jest kolumną int o wartości innej niż null: Profiles.

Co robię źle? Myślę, że trzymam się wszystkich konwencji EF Code First dotyczących zasad konfiguracji.

+0

Mogę się mylić, ale domyślną konwencją dla kolumn tożsamości jest właściwość o nazwie Id, czy próbowałeś zmienić PersonId na właśnie Id – ryudice

+0

Właściwie początkowo miałem wszystkie kolumny PK o nazwie po prostu Id. Próbując rozwiązać problem, zmieniłem je tak, jak pokazano w moim poście. Oryginalny post Scotta Gu na pierwszym miejscu miał DinnerID jako podstawowy klucz stołu obiadowego - http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework- 4.aspx –

Odpowiedz

32

będzie to nastąpić, jeśli należy wykonać następujące kroki:

  1. utworzyć pole PK bez tożsamości na stole.
  2. Podaj model jednostki z tego stołu.
  3. Wróć i ustaw tożsamość PK na true.

Model jednostki i baza danych są niezsynchronizowane. Odświeżenie modelu naprawi to. Musiałem to zrobić wczoraj.

+2

Jednak używam modelu kodu pierwszego EF4; nie ma pliku EDMX. EF przenosi mapowanie CSDL na SSDL poprzez konwencje nazewnictwa klas modeli. Istnieje również płynny interfejs do nadpisywania konwencji - którego tu nie używałem, ponieważ nie potrzebuję go w tym konkretnym przypadku. –

+2

Podstawowy problem polega na tym, że EF powinien generować instrukcję INSERT bez PersonId, ale nie jest (przydatny może być także Profiler).Nie jestem wystarczająco zaznajomiony z EF4, aby wiedzieć, gdzie flaga tożsamości jest utrzymywana, ale gdzieś w modelu model nie wie, że PersonId to tożsamość. Przepraszam, że nie jestem bardziej pomocny. –

+1

Niezły Chris, to był DOKŁADNIE mój problem. Kodowanie zbyt późno, z powodu zbyt małej ilości kawy, było przyczyną tego błędu dla mnie! Pozdrawiam :) – CountZero

43

I get the following error: Cannot insert explicit value for identity column in table 'People' when IDENTITY_INSERT is set to OFF.

Myślę, że IDENTITY_INSERT to funkcja automatycznego przyrostu, która jest wyłączona. Sprawdź więc pole PersonId w bazie danych, aby sprawdzić, czy jest to tożsamość.

Poza tym, może to również rozwiąże Twój problem.

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
public int PersonId { get; set; } 
+1

Miałem ten sam problem i naprawiłem go, ustawiając DatabaseGeneratedOption.Identity na OverMide OnModelCreating w DbContext –

+0

Sam problem również ja ustawiam DatabaseGeneratedOption.Identity na Entity oraz DbContext. Jak rozwiązać ten problem? Moja Db jest zlokalizowana na Azure. – Danilo

10

Jeśli używasz EF kod najpierw, potem, oprócz dodawania [DatabaseGeneratedAttribute (DatabaseGeneratedOption.Identity)] atrybut adnotacji do model.cs złożyć jak inni sugerują tu, również potrzebę dokonać tej samej skutecznej zmiany w modeluMap.Pliki CS (Fluent instrukcje mapowania):

Zmiana od:

this.Property(t => t.id) 
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 

do:

this.Property(t => t.id) 
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

(użyłem Narzędzia EF moc do generowania modeli Entity i pliki domyślne odwzorowania, następnie zmieniono jedną kolumnę identyfikatora na kluczową kolumnę klucza i ustawiono ją na IDENTITY na serwerze Sql, dlatego musiałem zaktualizować atrybut i domyślny plik mapowania.)

Jeśli nie zmieniaj je w obu miejscach, nadal będziesz mieć ten sam błąd.

0

W moim przypadku wydaje się, że EF nie lubi innego rodzaju niż INT tożsamości polu - kopalnia była BYTE (TINYINT po stronie SQL).

Ponieważ udało mi się zaktualizować mój projekt i zmienić go na INT na SQL, po ponownym uruchomieniu kodu Reverse Engineering Code na VisualStudio, błąd natychmiast przestał występować.

2

Twoja sytuacja przypomina mi sytuację, w której doświadczam kodu EF Najpierw, gdy PrimaryKey i ForeignKey są tą samą kolumną.

Nie ma bezpośredniego sposobu na odświeżenie modelu, jednak ten sam efekt można uzyskać w 2 krokach.

  1. Skomentuj ProfileId w klasie Profile. Rekompiluj i aktualizuj bazę danych.
  2. Odkomentuj identyfikator profilu, ponownie dodaj bazę danych DatabaseGeneratedAttribute i zaktualizuj bazę danych.

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None), Key]

ten sposób generowane kolumna ProfileID staje Key bez tożsamości.

+0

Czy to działa z migracją kodu? Rusztowanie nie generuje dla mnie. – William

3

nie miałem tego problemu aż dodałem kompozytowy klucza, więc gdy miałem 2 klucze podstawowe ten wystąpił z EF 6.xx

Na moim Key „id”, który ma Tożsamość Specyfikacja ustawiona na prawdziwego ja potrzebowałem dodać

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 

cechy modela teraz:

[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
[Key, Column("Id", Order = 1)] 
public int Id { get; set; } 

[Key, Column("RanGuid", Order = 2)] 
public string RanGuid { get; set; } 
0

In my case it seems that EF doesn't like other type than INT identity field - mine was a BYTE (TINYINT on the SQL side).

Miałem ten błąd również za pomocą PK typu tinyintel. To nie tak, że EF to nie podoba, to wydaje się, że, w przeciwieństwie do innych przypadków, trzeba określić, że w konfiguracji jak poniżej:

this.Property(t => t.TableID).HasColumnName("TableID").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
0

Oto rozwiązanie. Zobacz także załącznik, aby uzyskać dodatkową pomoc.

Przejdź do swojego modelu EF ".edmx "plik >> Otwórz to >> Teraz kliknij prawym przyciskiem myszy na diagramie i wybierz" Zaktualizuj model z bazy danych "

Naprawi to, ponieważ utworzyłeś PK tożsamości w twoim DB po utworzeniu modelu EF.

help to recreate steps stated above

2

z korzyścią dla poszukiwaczy.. mam ten błąd, ale powyższe poprawki nie działa to było spowodowane błędem z mojej strony

na moim tabel, mam Guid klucz podstawowy (nieklastrowy) i indeks int.

Błąd występujący podczas próby zaktualizowania "postu" z informacją "Blog" jako właściwością nawigacji. Zobacz klas poniżej:

public class Blog 
{ 
    public Guid BlogId { get; set; } 

    public int BlogIndex { get; set; } 

    // other stuff 
} 

public class Post 
{ 
    public Guid PostId { get; set; } 

    public int PostIndex { get; set; } 

    // other stuff 

    public Blog Blog { get; set; } 
} 

Kwestia ta była, że ​​kiedy konwersja DTO do modelach BlogId była zmieniona na new Guid() (zrobiłem błąd w mapowaniu). Wynikowy błąd był taki sam, jak podano w tym pytaniu.

Aby to naprawić, musiałem sprawdzić, czy dane były prawidłowe podczas wstawiania (nie było) i naprawić niepoprawną zmianę danych (w moim przypadku uszkodzone mapowanie).

+0

To samo dotyczyło mnie. Nie wstawiłem we właściwej kolejności moich danych, wstawiając model FK przed modelem PK, co powoduje błąd w mapowaniu tożsamości. –

1

Wystąpił ten błąd w EF6, przejrzałem bazę danych i wszystko wyglądało dobrze z numerem Identity Specification ustawionym na Yes. Następnie usunąłem różne migracje i wykonałem jedną nową migrację z bieżących modeli, a następnie wszystko zaczęło działać. Najszybsze rozwiązanie, ponieważ aplikacja nie była jeszcze na żywo i wciąż jest w fazie rozwoju.

enter image description here

Cannot insert explicit value for identity column in table 'Test' when IDENTITY_INSERT is set to OFF.

0

Jeśli używasz rdzeń EF i biegle interfejsu podobnego do mnie, znalazłem, że narzędzie rusztowań-DbContext użyłem do stworzenia modelu z istniejącego db, generują linia do mojego kolumny tak:

entity.Property(e => e.id).ValueGeneratedNever(); 

Po zmieniłem DB dodając atrybut tożsamość mojego id, musiałem zmienić wiersz:

entity.Property(e => e.id).ValueGeneratedOnAdd(); 

inne niż dodanie dekoratora [DatabaseGeneratedAttribute(DatabaseGeneratedOption.None), Key] do pola id w klasie mojego modelu.

Nie jestem nawet pewien, czy to drugie jest konieczne. Po rozwiązaniu poprzedniej poprawki nie próbowałem go usunąć.

Powiązane problemy