Entity Framework: tabela bez klucza podstawowego

Mam istniejący DB, z którym chciałbym zbudować nową aplikację za pomocą EF4. 0

Niektóre tabele nie mają zdefiniowanych kluczy podstawowych, więc kiedy tworzę nowy model danych encji, otrzymuję następujący komunikat: "table/view TABLE_NAME nie ma zdefiniowanego klucza podstawowego i nie można wywnioskować poprawnego klucza podstawowego. Ta tabela/Widok został wykluczony. Aby użyć encji, musisz przejrzeć swój schemat, dodać odpowiednie klucze i odkomentować go".

Jeśli chcę z nich korzystać i Modyfikuj dane, muszę koniecznie dodać PK do tych tabel, czy istnieje obejście, dzięki któremu nie muszę?

Author: vivek nuna, 2010-10-22

15 answers

Błąd oznacza dokładnie to, co mówi.

Nawet jeśli mógłbyś to obejść, zaufaj mi, nie chcesz. Liczba mylących błędów, które można wprowadzić, jest oszałamiająca i przerażająca, nie wspominając o tym, że Twoja wydajność prawdopodobnie spadnie.

Nie pracuj nad tym. Napraw swój model danych.

EDIT: widziałem, że wiele osób odrzuca to pytanie. W porządku, ale proszę pamiętać, że operacja poprosiła o odwzorowaniu tabeli bez klucza głównego, a nie widoku . Odpowiedź jest wciąż taka sama. Obejście potrzeby EF, aby mieć PK na tabelach, jest złym pomysłem z punktu widzenia zarządzania, integralności danych i wydajności.

Niektórzy skomentowali, że nie mają możliwości naprawy bazowego modelu danych, ponieważ są mapowane do aplikacji innych firm. To nie jest dobry pomysł, ponieważ model może się zmienić spod ciebie. Prawdopodobnie, w takim przypadku, ty chciałbym mapować do widoku, co, znowu, nie jest tym, o co prosiło OP.

 53
Author: Dave Markle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-03 09:18:35

Myślę, że to jest rozwiązane przez Tillito:

Entity Framework i widok SQL Server

Zacytuję jego wpis poniżej:

Mieliśmy ten sam problem i jest to rozwiązanie:

Aby wymusić użycie kolumny jako klucza podstawowego, użyj ISNULL.

Aby wymusić, aby struktura encji nie używała kolumny jako klucza podstawowego, użyj NULLIF.

Łatwym sposobem zastosowania tego polecenia jest zawinięcie instrukcji select widoku w inną wybierz.

Przykład:

SELECT
  ISNULL(MyPrimaryID,-999) MyPrimaryID,
  NULLIF(AnotherProperty,'') AnotherProperty
  FROM ( ... ) AS temp

Odpowiedział 26 kwietnia '10 o 17: 00 przez Tillito

 100
Author: Colin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:43

Klucze złożone mogą być również wykonywane za pomocą interfejsu Entity Framework Fluent API

public class MyModelConfiguration : EntityTypeConfiguration<MyModel>
{
     public MyModelConfiguration()
     {
        ToTable("MY_MODEL_TABLE");
        HasKey(x => new { x.SourceId, x.StartDate, x.EndDate, x.GmsDate });
        ...
     }
}
 10
Author: Adrian Garcia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-18 14:42:01

W moim przypadku musiałem zmapować obiekt do widoku, który nie miał klucza głównego. Co więcej, nie mogłem modyfikować tego widoku. Na szczęście Widok ten miał kolumnę, która była unikalnym ciągiem. Moim rozwiązaniem było oznaczyć tę kolumnę jako klucz główny:

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[StringLength(255)]
public string UserSID { get; set; }

Oszukany EF. Działa idealnie, nikt nie zauważył... :)

 5
Author: Boris Lipschitz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-11 01:18:46

TO ROZWIĄZANIE DZIAŁA

Nie musisz mapować ręcznie, nawet jeśli nie masz PK. Musisz tylko powiedzieć EF, że jedna z Twoich kolumn to index, a Kolumna index nie jest nullable.

Aby to zrobić, możesz dodać numer wiersza do widoku za pomocą funkcji isNull, jak poniżej

select 
    ISNULL(ROW_NUMBER() OVER (ORDER BY xxx), - 9999) AS id
from a

ISNULL(id, number) jest tu kluczowym punktem, ponieważ mówi EF, że ta kolumna może być kluczem głównym

 5
Author: Barny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-08 13:46:32

EF nie wymaga klucza podstawowego w bazie danych. Gdyby tak było, nie można by powiązać Bytów z widokami.

Możesz zmodyfikować SSDL (i CSDL), aby określić unikalne pole jako klucz główny. Jeśli nie masz wyjątkowego pola, to wierzę, że jesteś naćpany. Ale naprawdę powinieneś mieć unikalne pole (i PK), w przeciwnym razie napotkasz później problemy.

Erick

 4
Author: Erick T,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-22 20:20:44

Jeśli chcę ich używać i modyfikować dane, muszę koniecznie dodać PK do tych tabel, czy istnieje obejście, dzięki któremu nie muszę?

Dla tych, którzy zadają to pytanie i używają rdzenia Entity Framework, nie musisz już koniecznie dodawać PK do tych tabel lub wykonywać żadnego obejścia. Od EF Core 2.1 mamy nową funkcję typów zapytań

Typy zapytań muszą być używane dla:

  • służąca jako typ powrotu dla ad hoc Zapytania FromSql ().
  • mapowanie do widoków bazy danych.
  • mapowanie do tabel, które nie mają zdefiniowanego klucza podstawowego.
  • mapowanie do zapytań zdefiniowanych w modelu.

Więc w DbContext wystarczy dodać następującą właściwość typu DbQuery<T> zamiast DbSet<T> Jak Poniżej. Zakładając, że nazwa tabeli to MyTable:

public DbQuery<MyTable> MyTables { get; set; }
 3
Author: CodeNotFound,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-30 10:13:35

Powyższe odpowiedzi są poprawne, jeśli naprawdę nie masz PK.

Ale jeśli jest taki, ale nie jest określony indeksem w DB i nie możesz zmienić DB (tak, pracuję w świecie Dilberta), możesz ręcznie mapować pola jako klucz.

 2
Author: Poker Villain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-22 14:50:51

Posiadanie bezużytecznego klucza tożsamości jest czasami bezcelowe. Jeśli identyfikator nie jest używany, po co go dodawać? Jednak Encja nie jest tak wyrozumiała, więc dodanie pola ID byłoby najlepsze. Nawet w przypadku, gdy nie jest używany, jest to lepsze niż radzenie sobie z nieustannymi błędami podmiotu dotyczącymi brakującego klucza tożsamości.

 2
Author: IyaTaisho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-28 17:42:07

To tylko dodatek do odpowiedzi @ Erick T. Jeśli nie ma pojedynczej kolumny z unikalnymi wartościami, obejściem jest użycie klucza złożonego w następujący sposób:

[Key]
[Column("LAST_NAME", Order = 1)]
public string LastName { get; set; }

[Key]
[Column("FIRST_NAME", Order = 2)]
public string FirstName { get; set; }
To tylko obejście. Prawdziwym rozwiązaniem jest naprawienie modelu danych.
 2
Author: Developer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-09 11:18:27
  1. zmiana struktury tabeli i dodanie kolumny podstawowej. Zaktualizuj Model
  2. zmodyfikuj .Plik EDMX w edytorze XML i spróbuj dodać nową kolumnę pod tagiem dla tej konkretnej tabeli (nie zadziała)
  3. zamiast tworzyć nową kolumnę główną do wyjścia tabeli, będę Utwórz klucz złożony, angażując wszystkie istniejące kolumny ( )

Entity Framework: dodawanie DataTable bez klucza podstawowego do modelu Entity.

 1
Author: Pratap,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-23 14:40:37

To może za późno na odpowiedź...jednak...

Jeśli tabela nie ma klucza podstawowego, istnieje kilka scenariuszy, które należy przeanalizować, aby EF działał poprawnie. Zasada jest następująca: EF będzie pracować z tabelami/klasami z kluczem podstawowym. Tak to robi śledzenie...

Powiedz, Twój stół 1. Rekordy są unikalne: wyjątkowość jest dokonywana przez jedną kolumnę klucza obcego: 2. Rekordy są unikalne: wyjątkowość jest tworzona przez kombinację wielu kolumn. 3. Zapisy nie są unikalne (w większości*).

Dla scenariuszy #1 i # 2 możesz dodać następującą linię do modułu DbContext OnModelCreating metody: modelBuilder.Entity ().HasKey (x => new { x. column_a, x. column_b}); / / tyle kolumn, ile potrzeba, aby rekordy były unikalne.

Dla scenariusza # 3 nadal możesz użyć powyższego rozwiązania (#1 + #2) po przestudiowaniu tabeli (*co sprawia, że wszystkie rekordy są unikalne). Jeśli musisz zawierać wszystkie kolumny, aby wszystkie rekordy były unikalne, możesz dodać główna kolumna kluczowa do tabeli. Jeśli ta tabela pochodzi od innego dostawcy, Klonuj tę tabelę do lokalnej bazy danych (przez noc lub tyle czasu, ile potrzebujesz) z kolumną klucza podstawowego dodaną dowolnie przez skrypt klonowania.

 1
Author: Sam Saarian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-09 12:01:57

Z praktycznego punktu widzenia, każda tabela -- nawet tabela denormalizowana jak tabela magazynowa -- powinna mieć klucz główny. Lub, w przeciwnym razie, powinien mieć co najmniej unikalny, Nie nullable indeks.

Bez pewnego rodzaju unikalnego klucza duplikaty rekordów mogą (i będą) pojawiać się w tabeli, co jest bardzo problematyczne zarówno dla warstw ORM, jak i dla podstawowego zrozumienia danych. Tabela, która ma zduplikowane rekordy, jest prawdopodobnie objawem złego projektu.

At the very least, tabela powinna mieć przynajmniej kolumnę identity. Dodanie automatycznie generującej kolumny ID zajmuje około 2 minut w SQL Server i 5 minut w Oracle. Dla tego dodatkowego wysiłku, Wiele, Wiele problemów zostanie unikniętych.

 0
Author: Ash8087,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-06 14:57:57

Napotkaliśmy również ten problem i chociaż mieliśmy kolumnę, która miała null, ważne było to, że mieliśmy kolumnę zależną, która nie miała null i że kombinacja tych dwóch kolumn była wyjątkowa.

Więc cytując odpowiedź udzieloną przez Pratap Reddy ' ego, zadziałało dobrze dla nas.

 0
Author: Azerax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-21 13:32:33

Tabela musi mieć tylko jedną kolumnę, która nie zezwala na null

 -6
Author: mister9,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-12 20:52:40