AKTUALIZACJA: Ostatnio otrzymałem kilka pozytywnych opinii na ten temat, więc pomyślałem, że dam znać ludziom, że poniższe porady nie są najlepsze. Odkąd zacząłem się zastanawiać, wykonując Entity Framework na starych bazach danych bezkluczykowych, zdałem sobie sprawę, że najlepszą rzeczą, jaką możesz zrobić BY FAR, jest zrobienie tego przez odwrócenie kodu. Istnieje kilka dobrych artykułów na ten temat. Postępuj zgodnie z nimi, a następnie, jeśli chcesz dodać klucz, użyj adnotacji danych, aby „sfałszować” klucz.
Załóżmy na przykład, że wiem, że mój stół Orders
, chociaż nie ma klucza podstawowego, gwarantuje, że będzie miał tylko jeden numer zamówienia na klienta. Ponieważ są to dwie pierwsze kolumny w tabeli, ustawiłem pierwsze klasy kodu, aby wyglądały następująco:
[Key, Column(Order = 0)]
public Int32? OrderNumber { get; set; }
[Key, Column(Order = 1)]
public String Customer { get; set; }
Robiąc to, w zasadzie sfałszujesz EF, aby uwierzyć, że istnieje klastrowany klucz złożony z OrderNumber i Customer. Umożliwi to wykonywanie wstawek, aktualizacji itp. W tabeli bezkluczykowej.
Jeśli nie jesteś zbyt zaznajomiony z robieniem kodu w pierwszej kolejności, znajdź dobry samouczek na temat Entity Framework Code First. Następnie znajdź jeden w Odwróć kod pierwszy (który robi kod pierwszy z istniejącą bazą danych). Więc po prostu wróć tutaj i ponownie spójrz na moją kluczową radę. :)
Oryginalna odpowiedź :
Po pierwsze: jak powiedzieli inni, najlepszą opcją jest dodanie klucza podstawowego do tabeli. Kropka. Jeśli możesz to zrobić, nie czytaj dalej.
Ale jeśli nie możesz lub po prostu nienawidzisz siebie, istnieje sposób, aby to zrobić bez klucza podstawowego.
W moim przypadku pracowałem ze starszym systemem (pierwotnie płaskie pliki na AS400 przeniesione do Access, a następnie przeniesione do T-SQL). Musiałem więc znaleźć sposób. To jest moje rozwiązanie. Poniższe działało dla mnie przy użyciu Entity Framework 6.0 (najnowsza wersja NuGet w chwili pisania tego tekstu).
Kliknij prawym przyciskiem myszy plik .edmx w Eksploratorze rozwiązań. Wybierz „Otwórz za pomocą ...”, a następnie wybierz „Edytor XML (tekst)”. Będziemy tutaj ręcznie edytować automatycznie wygenerowany kod.
Poszukaj takiej linii:
<EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" store:Schema="dbo" store:Name="table_nane">
Usuń store:Name="table_name"
z końca.
Zmień store:Schema="whatever"
naSchema="whatever"
Spójrz poniżej tego wiersza i znajdź <DefiningQuery>
tag. Będzie miał w nim dużą, starą instrukcję. Usuń tag i jego zawartość.
Teraz twoja linia powinna wyglądać mniej więcej tak:
<EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />
Mamy coś jeszcze do zmiany. Przejrzyj plik i znajdź to:
<EntityType Name="table_name">
W pobliżu prawdopodobnie zobaczysz komentarz z ostrzeżeniem, że nie zidentyfikowano klucza podstawowego, więc klucz został wyprowadzony, a definicja jest tabelą / widokiem tylko do odczytu. Możesz go zostawić lub usunąć. Usunąłem to.
Poniżej znajduje się <Key>
tag. Tego właśnie używa Entity Framework do wstawiania / aktualizacji / usuwania. UPEWNIJ SIĘ, ŻE ROBISZ PRAWO. Właściwość (lub właściwości) w tym znaczniku muszą wskazywać jednoznacznie identyfikowalny wiersz. Załóżmy na przykład, że wiem, że mój stół orders
, chociaż nie ma klucza podstawowego, gwarantuje, że będzie miał tylko jeden numer zamówienia na klienta.
Mój wygląda więc tak:
<EntityType Name="table_name">
<Key>
<PropertyRef Name="order_numbers" />
<PropertyRef Name="customer_name" />
</Key>
Poważnie, nie róbcie tego źle. Powiedzmy, że chociaż nigdy nie powinno być duplikatów, jakoś dwa wiersze dostają się do mojego systemu z tym samym numerem zamówienia i nazwą klienta. Whooops! To właśnie dostaję za nieużywanie klucza! Więc używam Entity Framework, aby go usunąć. Ponieważ wiem, że duplikat jest jedynym zamówieniem złożonym dzisiaj, robię to:
var duplicateOrder = myModel.orders.First(x => x.order_date == DateTime.Today);
myModel.orders.Remove(duplicateOrder);
Zgadnij co? Właśnie usunąłem zarówno duplikat, jak i oryginał! Dzieje się tak, ponieważ powiedziałem Entity Framework, że numer_kolejny / nazwa_komeru to mój klucz podstawowy. Więc kiedy powiedziałem mu, aby usunąć duplikat zamówienia, to w tle było coś takiego:
DELETE FROM orders
WHERE order_number = (duplicateOrder's order number)
AND customer_name = (duplicateOrder's customer name)
I z tym ostrzeżeniem ... powinieneś już iść!