Najpierw używam kodu Entity Framework 5.0;
public class Entity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public string EntityId { get; set;}
public int FirstColumn { get; set;}
public int SecondColumn { get; set;}
}
Chcę zrobić kombinację między FirstColumn
i SecondColumn
tak wyjątkowy.
Przykład:
Id FirstColumn SecondColumn
1 1 1 = OK
2 2 1 = OK
3 3 3 = OK
5 3 1 = THIS OK
4 3 3 = GRRRRR! HERE ERROR
Czy istnieje jakiś sposób, aby to zrobić?
entity-framework
ef-code-first
constraints
multiple-columns
unique-key
Bassam Alugili
źródło
źródło
Znalazłem trzy sposoby rozwiązania problemu.
Unikalne indeksy w EntityFramework Core:
Pierwsze podejście:
Drugie podejście do tworzenia unikalnych ograniczeń za pomocą EF Core za pomocą alternatywnych kluczy.
Przykłady
Jedna kolumna:
Wiele kolumn:
EF 6 i poniżej:
Pierwsze podejście:
To podejście jest bardzo szybkie i przydatne, ale głównym problemem jest to, że Entity Framework nie wie nic o tych zmianach!
Drugie podejście:
znalazłem to w tym poście, ale nie próbowałem sam.
Problem tego podejścia jest następujący: Wymaga DbMigration, więc co robisz, jeśli go nie masz?
Trzecie podejście:
myślę, że jest to najlepsze, ale zajmuje to trochę czasu. Pokażę ci po prostu pomysł: w tym linku http://code.msdn.microsoft.com/CSASPNETUniqueConstraintInE-d357224a można znaleźć kod unikalnej adnotacji danych kluczowych:
Problem tego podejścia; Jak mogę je połączyć? Mam pomysł na rozszerzenie tej implementacji Microsoft na przykład:
Później w IDatabaseInitializer, jak opisano w przykładzie Microsoft, możesz łączyć klucze zgodnie z podaną liczbą całkowitą. Należy jednak zwrócić uwagę na jedno: jeśli unikalna właściwość jest typu string, musisz ustawić MaxLength.
źródło
CREATE UNIQUE INDEX ix_{1}_{2} ON {0} ({1}, {2})
:? (patrz BOL )Jeśli używasz Code-First , możesz zaimplementować niestandardowe rozszerzenie HasUniqueIndexAnnotation
Następnie użyj go w następujący sposób:
Co spowoduje migrację:
I ostatecznie trafiają do bazy danych jako:
źródło
this.Property(t => t.Email)
)? (tj. co to jestthis
)EntityTypeConfiguration<T>
Musisz zdefiniować klucz złożony.
Z adnotacjami danych wygląda to tak:
Można to również zrobić za pomocą modeluBuilder podczas nadpisywania OnModelCreating, określając:
źródło
Odpowiedź od niaher stwierdzająca, że do korzystania z płynnego interfejsu API potrzebujesz niestandardowego rozszerzenia, mogła być poprawna w momencie pisania. Możesz teraz (EF core 2.1) korzystać z płynnego API w następujący sposób:
źródło
Wypełnianie odpowiedzi @chuck za używanie indeksów złożonych z kluczami obcymi .
Musisz zdefiniować właściwość, która będzie przechowywać wartość klucza obcego. Następnie możesz użyć tej właściwości w definicji indeksu.
Na przykład mamy firmę z pracownikami i tylko mamy wyjątkowe ograniczenie (nazwa, firma) dla każdego pracownika:
Teraz mapowanie klasy Employee:
Zauważ, że użyłem rozszerzenia @niaher do unikalnej adnotacji indeksu.
źródło
W zaakceptowanej odpowiedzi @chuck znajduje się komentarz mówiący, że nie zadziała w przypadku FK.
zadziałało dla mnie, sprawa EF6 .Net4.7.2
źródło
Zakładam, że zawsze chcesz
EntityId
być kluczem podstawowym, więc zastąpienie go kluczem złożonym nie jest opcją (choćby dlatego, że klucze złożone są znacznie bardziej skomplikowane w pracy i ponieważ nie jest bardzo sensowne mieć klucze podstawowe, które również mają znaczenie w logice biznesowej).Co najmniej powinieneś zrobić, to utworzyć unikalny klucz dla obu pól w bazie danych i szczególnie sprawdzić wyjątki naruszenia wyjątków podczas zapisywania zmian.
Dodatkowo możesz (powinieneś) sprawdzić unikalne wartości przed zapisaniem zmian. Najlepszym sposobem na to jest
Any()
zapytanie, ponieważ minimalizuje ilość przesyłanych danych:Uważaj, że sama kontrola nigdy nie wystarczy. Zawsze występuje pewne opóźnienie między sprawdzeniem a rzeczywistym zatwierdzeniem, więc zawsze będziesz potrzebować unikalnego ograniczenia + obsługi wyjątków.
źródło
Ostatnio dodałem klucz złożony z wyjątkowością 2 kolumn, stosując podejście zalecane przez „chuck”, dziękuję @ chuck. Tylko to podejście wydawało mi się czystsze:
źródło