Mam istniejącą bazę danych, za pomocą której chciałbym zbudować nową aplikację przy użyciu EF4.0
Niektóre tabele nie mają zdefiniowanych kluczy podstawowych, więc kiedy tworzę nowy Entity Data Model, otrzymuję następujący komunikat:
The table/view TABLE_NAME does not have a primary key defined
and no valid primary key could be inferred. This table/view has
been excluded. To use the entity, you will need to review your schema,
add the correct keys, and uncomment it.
Jeśli chcę ich używać i modyfikować dane, czy koniecznie muszę dodać PK do tych tabel, czy też istnieje obejście, aby nie musieć tego robić?
.net
entity-framework
Kryzys
źródło
źródło
Odpowiedzi:
Błąd oznacza dokładnie to, co mówi.
Nawet gdybyś mógł 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 w dół.
Nie omijaj tego. Napraw model danych.
EDYCJA: Widziałem, że wiele osób odrzuca to pytanie. Przypuszczam, że to w porządku, ale pamiętaj, że OP zapytał o mapowanie tabeli bez klucza podstawowego, a nie widoku . Odpowiedź jest wciąż taka sama. Obchodzenie się z potrzebą posiadania PK na tabelach jest złym pomysłem z punktu widzenia możliwości zarządzania, integralności danych i wydajności.
Niektórzy zauważyli, że nie mają możliwości naprawienia bazowego modelu danych, ponieważ mapują do aplikacji innej firmy. To nie jest dobry pomysł, ponieważ model może się zmienić spod ciebie. Prawdopodobnie w takim przypadku chciałbyś zmapować do widoku, który znowu nie jest tym, o co prosił PO.
źródło
Myślę, że rozwiązuje to Tillito:
Entity Framework i widok SQL Server
Zacytuję jego wpis poniżej:
Mieliśmy ten sam problem i oto rozwiązanie:
Aby zmusić strukturę jednostki do używania kolumny jako klucza podstawowego, użyj ISNULL.
Aby wymusić na platformie jednostki, aby nie używała kolumny jako klucza podstawowego, użyj wartości NULLIF.
Łatwym sposobem na zastosowanie tego jest zawinięcie wyrażenia select swojego widoku w innym select.
Przykład:
odpowiedział 26 kwietnia 2010 o 17:00 przez Tillito
źródło
Osoby, które dotarły do tego pytania i korzystają z Entity Framework Core, nie muszą już koniecznie dodawać PK do tych tabel ani wykonywać żadnego obejścia. Od EF Core 2,1 mamy nowe typy zapytań funkcji
Typy zapytań muszą być używane dla:
Więc w swoim DbContext po prostu dodaj następującą właściwość type
DbQuery<T>
zamiastDbSet<T>
jak poniżej. Zakładając, że nazwa twojej tabeli toMyTable
:źródło
Klucze złożone można również wykonać za pomocą interfejsu API Entity Framework Fluent
źródło
modelBuilder.Entity<T>()
wywołanie łańcuchowe.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)
za pomocą tych och tak specjalnych kluczy, które nie są naturalne ani złożone, ale można na nich polegać był wyjątkowy (tak czy inaczej)W moim przypadku musiałem zmapować jednostkę do widoku, który nie miał klucza podstawowego. Ponadto nie wolno mi było modyfikować tego widoku. Na szczęście ten widok miał kolumnę, która była unikalnym ciągiem. Moim rozwiązaniem było oznaczenie tej kolumny jako klucza podstawowego:
Oszukany EF. Działało idealnie, nikt nie zauważył ... :)
źródło
UserID
kolumnę, jeśli używasz podejścia Code First ..!Itentity
funkcji. Zasadniczo, jeśli mam rację, nadal utworzyUserID
dla ciebie kolumnę jako PK, ale nie zwiększy automatycznieUserID
podczas tworzenia nowego rekordu, jak byłoby to domyślnie. Ponadto nadal musisz zachować różne wartości wUserID
.EF nie wymaga klucza podstawowego w bazie danych. Gdyby tak było, nie można by powiązać jednostek z widokami.
Możesz zmodyfikować SSDL (i CSDL), aby określić unikalne pole jako klucz podstawowy. Jeśli nie masz unikalnego pola, uważam, że jesteś wężem. Ale naprawdę powinieneś mieć unikalne pole (i PK), w przeciwnym razie napotkasz później problemy.
Erick
źródło
Posiadanie bezużytecznego klucza tożsamości jest czasami bezcelowe. Znajduję, jeśli identyfikator nie jest używany, po co go dodawać? Jednak Entity nie wybacza w tej kwestii, więc najlepiej byłoby dodać pole ID. Nawet w przypadku, gdy nie jest używany, jest to lepsze niż radzenie sobie z nieustannymi błędami Entity dotyczącymi brakującego klucza tożsamości.
źródło
TO ROZWIĄZANIE DZIAŁA
Nie musisz mapować ręcznie, nawet jeśli nie masz PK. Wystarczy poinformować EF, że jedna z kolumn jest indeksowana, a kolumna indeksu nie dopuszcza wartości null.
Aby to zrobić, możesz dodać numer wiersza do swojego widoku za pomocą funkcji isNull, jak poniżej
ISNULL(id, number)
jest tutaj kluczowym punktem, ponieważ informuje EF, że ta kolumna może być kluczem podstawowymźródło
Powyższe odpowiedzi są poprawne, jeśli naprawdę nie masz PK.
Ale jeśli istnieje, ale po prostu nie jest określony indeksem w bazie danych, i nie możesz zmienić bazy danych (tak, pracuję w świecie Dilberta), możesz ręcznie zmapować pole (pola) jako klucz.
źródło
To tylko dodatek do odpowiedzi @Erick T. Jeśli nie ma jednej kolumny z unikatowymi wartościami, obejściem jest użycie klucza złożonego w następujący sposób:
Ponownie, to tylko obejście. Prawdziwym rozwiązaniem jest naprawienie modelu danych.
źródło
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 taka: EF będzie działał z tabelami / klasami z kluczem podstawowym. W ten sposób śledzi ...
Powiedzmy, twoja tabela 1. Rekordy są niepowtarzalne: niepowtarzalność jest określana przez pojedynczą kolumnę klucza obcego: 2. Rekordy są niepowtarzalne: niepowtarzalność tworzy kombinacja wielu kolumn. 3. Rekordy nie są unikalne (w większości *).
W scenariuszach nr 1 i 2 można dodać następujący wiersz do metody OnModelCreating modułu DbContext: modelBuilder.Entity (). HasKey (x => new {x.column_a, x.column_b}); // tyle kolumn, ile potrzeba, aby rekordy były unikalne.
W scenariuszu # 3 możesz nadal korzystać z powyższego rozwiązania (# 1 + # 2) po przestudiowaniu tabeli (* co i tak sprawia, że wszystkie rekordy są unikalne). Jeśli musisz uwzględnić WSZYSTKIE kolumny, aby wszystkie rekordy były unikalne, możesz dodać kolumnę klucza podstawowego do swojej tabeli. Jeśli ta tabela pochodzi od zewnętrznego dostawcy, sklonuj ją do lokalnej bazy danych (przez noc lub tyle razy, ile potrzebujesz) z kolumną klucza podstawowego dodaną dowolnie za pośrednictwem skryptu klonowania.
źródło
Entity Framework: dodawanie DataTable bez klucza podstawowego do modelu jednostki.
źródło
Zaktualizuj do odpowiedzi @CodeNotFound .
W EF Core 3,0
DbQuery<T>
został przestarzały, zamiast tego należy używać typów jednostek bez kluczy, które rzekomo robią to samo. Są one konfigurowane za pomocąHasNoKey()
metody ModelBuilder . Zrób to w swojej klasie DbContextIstnieją jednak ograniczenia, w szczególności:
Oznacza to, że na pytanie
Nie możesz modyfikować danych w ten sposób - możesz jednak czytać. Można sobie jednak wyobrazić użycie innego sposobu (np. ADO.NET, Dapper) do modyfikowania danych - może to być rozwiązanie w przypadkach, gdy rzadko trzeba wykonywać operacje bez odczytu i nadal chciałbyś trzymać się EF Core w większości przypadków.
Ponadto, jeśli naprawdę potrzebujesz / chcesz pracować z tabelami sterty (bezkluczowymi) - rozważ porzucenie EF i użyj innego sposobu, aby rozmawiać z bazą danych.
źródło
Z praktycznego punktu widzenia każdy stół - nawet zdenormalizowany, taki jak stół magazynowy - powinien mieć klucz podstawowy. Lub, w przeciwnym razie, powinien mieć przynajmniej unikalny indeks nie dopuszczający wartości null.
Bez jakiegoś unikalnego klucza zduplikowane rekordy 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 zawiera zduplikowane rekordy, jest prawdopodobnie objawem złego projektu.
Przynajmniej tabela powinna mieć przynajmniej kolumnę tożsamości. Dodanie automatycznie generowanej kolumny ID trwa około 2 minut w SQL Server i 5 minut w Oracle. Za ten dodatkowy wysiłek można uniknąć wielu, wielu problemów.
źródło
Napotkaliśmy również ten problem i chociaż mieliśmy kolumnę zawierającą wartości null, ważne było to, że mieliśmy kolumnę zależną, która nie zawierała wartości null, i że połączenie tych dwóch kolumn było unikalne.
Cytując odpowiedź udzieloną przez Pratapa Reddy'ego, zadziałało to dobrze dla nas.
źródło
Bardzo się cieszę, że mój problem został rozwiązany.
Nie można zaktualizować EntitySet - ponieważ ma DefiningQuery i nie istnieje element <UpdateFunction>
i zrób to: Spójrz poniżej tej linii i znajdź znacznik. Będzie zawierał dużą, starą instrukcję select. Usuń tag i jego zawartość.
teraz bez zmiany DB TI może wstawiać do tabeli, która nie ma PK
dziękuję wszystkim i dziękuję Pharylon
źródło
W EF Core 5,0 będzie można również zdefiniować go na poziomie jednostki.
Źródła: https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-5.0/whatsnew#use-ac-attribute-to-indicate-that-an-entity- nie ma klucza
źródło
Tabela musi mieć tylko jedną kolumnę, która nie zezwala na wartości null
źródło