2012-06-29 11 views
5

Ponieważ EF nie obsługuje unikalnych ograniczeń klawiszy, wydaje się, że musimy uchwycić wyjątek podczas zapisywania metody i wyświetlić komunikat o błędzie użytkownikowi.Kod EF Pierwszy proces obsługi wyjątków bazy danych podczas zapisywania zmian

Problemy z tego podejścia są:

  • skąd wiemy, które rejestrują zwrócił wyjątek
  • Skąd wiemy, jaki rodzaj problemu zwrócił wyjątek (ex mogę mieć dwie unikalne ograniczeń na same rekord, więc muszę poinformować użytkownika, który z nich jest uszkodzona)

DBMS jest SqlServer 2008.

Jak rozwiązać te problemy?

Odpowiedz

2

Jeśli pozwolisz, że użytkownik może wprowadzić wartości, które muszą być unikatowe w bazie danych należy zweryfikować to wejście przed zapisaniem zmian:

if (context.Customers.Any(c => c.SomeUniqueProperty == userInput)) 
    // return to user with a message to change the input value 
else 
    context.SaveChanges(); 

to nie tylko w przypadku wartości z unikalnych ograniczeń w bazie danych, ale także do wprowadzania wartości kluczy obcych, które muszą odnosić się do istniejących rekordów docelowych lub wartości kluczy podstawowych, jeśli klucz podstawowy nie jest automatycznie generowany w bazie danych. EF nie pomaga ci w tej ostatniej sytuacji, ponieważ kontekst nie zna zawartości całej tabeli bazy danych, ale tylko o obiektach, które są obecnie dołączone do kontekstu. Prawdą jest, że EF zabroni dołączania dwóch obiektów z tym samym kluczem podstawowym, ale zezwala na dwa obiekty z tym samym unikalnym ograniczeniem klucza. Ale to nie chroni cię całkowicie przed naruszeniem ograniczeń klucza podstawowego podczas zapisywania zmian w bazie danych.

W mało prawdopodobnym przypadku, w którym inny użytkownik wpisałby rekord o tej samej wartości, uznałbym wyjątek za niemożliwy do obsłużenia i po prostu powiedziałem użytkownikowi "Wystąpił oczekiwany błąd, spróbuj jeszcze raz...". Jeśli użytkownik spróbuje ponownie, test zostanie przeprowadzony ponownie, a otrzyma bardziej przydatny komunikat do zmiany wartości wejściowej z powyższego kodu.

Wyjątkiem zwróconym w przypadku takiego ograniczenia ograniczenia klucza lub naruszenia klucza podstawowego jest ogólne DbUpdateException, a jednym z wewnętrznych wyjątków będzie SqlException, który jako jedną z jego właściwości zawiera kod błędu SQL Server. Wszelkie inne szczegóły można znaleźć tylko w komunikacie wyjątku "Naruszenie UNIKALNEGO KLUCZOWEGO ograniczenia IX_SomeUniqueProperty_Index ..." lub podobnego. Jeśli spodziewasz się, że użytkownik może zrozumieć i odpowiednio zareagować na te informacje, możesz je wyświetlić. W przeciwnym razie możesz zalogować tę wiadomość dla administratora lub programisty, aby sprawdzić możliwe błędy lub inne problemy.

+0

Tak więc, ponieważ wykonuję aktualizacje wsadowe, wymagałoby to znalezienia zaktualizowanych/dodanych rekordów w klientach i przechodzenia do każdego rekordu w celu sprawdzenia, czy istnieje istniejący rekord o tej samej wartości. Nie jestem do końca pewny, jak wpłynie to na wydajność, gdy zmieni się ponad 10 rekordów. Czy w takim przypadku lepiej po prostu złapać wyjątek? Wiadomość musi być zlokalizowana, więc wydaje mi się, że muszę utworzyć procedurę, która wykona wyszukiwanie wiadomości dla IX_SomeUniqueProperty, ponieważ wiadomość może być również w języku francuskim, jeśli system operacyjny jest francuski (jeśli się nie mylę) i nie mogę polegać w sprawie "Naruszenie ..." – Goran

+0

@Goran: Rozumiem, ale nadal robiłbym zapytanie, by sprawdzić istnienie. Jeśli musisz także * aktualizować * tak, jak mówisz, nie tylko wstawiać, czy nie musisz w ogóle pytać o encję w bazie danych? Nie można zdecydować między aktualizowaniem a wstawianiem bez wiedzy, czy jednostka jest już w bazie danych, czy nie. – Slauma

+0

Decyzję pomiędzy aktualizacją a wstawianiem podejmuje sam EF.Każda jednostka, którą dodałem do kolekcji klientów, jest traktowana jako nowy rekord, rekordy z już przypisanymi PK zostaną zaktualizowane. To, co muszę uwzględnić, to przypadek, w którym użytkownik sieci dodał rekord (dane klienta są w większości przypadków nieaktualne z danymi bazy danych, ponieważ wymagałoby to ciągłej resynchronizacji), więc między ostatnim a 15 minutami ładowanie danych i zapisywanie wywołań zmian. Z tego powodu nie mogę polegać tylko na danych, które są buforowane na kliencie, aby sprawdzić, czy są to ograniczenia unikalne (lub jakiekolwiek inne). – Goran

Powiązane problemy