Usuwanie rekordów | Ilaro.Admin
Podczas usuwania rekordu zawsze jest wyświetlana strona do potwierdzenia.
W wersji v2 będę to chciał zmienić. Chciałbym dodać opcję potwierdzania w oknie modalnym (lub w podobny sposób) a także możliwość kompletnego usunięcia potrzeby usunięcia, w przypadku gdy usuwanie encji jest robione poprzez soft delete. Po usunięciu pojawiałaby się opcja umożliwiająca cofnięcie usuwania.
Klucze obce
Podstawowym problemem podczas usuwania rekordu są jego zależności.
Trzeba zadbać o to by przed usunięciem rekordu inne rekordy nie będą miały do niego referencji.
Można to zrobić na dwa sposoby, albo poprzez usunięcie rekordów z referencjami, albo odpięcie usuwanego rekordu od rekordów z referencjami.
Ilaro.Admin umożliwia ustawienie tych opcji dla kluczy obcych, dodatkowo można określić, że nie chcemy robić nic robić z kluczem obcym lub ma być wyświetlony formularz, który pozwoli na wybranie tych opcji przez użytkownika.
1 2 3 4 5 6 7 |
public enum CascadeOption : int { Nothing = 0, Detach = 1, Delete = 2, AskUser = 3 } |
Fluent konfiguracja:
1 2 3 4 |
Property(x => x.Orders, x => { x.Cascade(CascadeOption.Delete); }); |
Konfiguracja atrybutami:
1 2 |
[Cascade(CascadeOption.Delete)] public virtual ICollection<Order> Orders { get; set; } |
Kaskadowe usuwanie
Na stronie potwierdzającej usunięcie wyświetlana jest lista rekordów, które zostaną usunięte jeśli została wybrana metoda kaskadowego usuwania.
Oczywiście jeśli w encji Order, zmienna OrderDetail będzie ustawiona na CascadeOption.Detach , to żaden rekord OrderDetail nie pojawi się na tej liście.
Przykładowy wygenerowany SQL:
1 2 3 4 |
DELETE [t1] FROM [Orders] [t1] LEFT OUTER JOIN [Customers] AS [t0] ON [t0].[CustomerID] = [t1].[CustomerID] WHERE [t0].[CustomerID] = @0; |
@0 – parametr z wartością klucza usuwanego rekordu
Odpinanie rekordów
Jeśli klucz obcy jest zdefiniowany na
CascadeOption.Detach , wtedy w rekordach posiadających referencje do usuwanego rekordu, wartość klucza obcego jest ustawiana na Null.
Oczywiście zadziałała to tylko wtedy gdy klucz obcy będzie nullable.
Przykładowy wygenerowany SQL:
1 2 3 4 5 |
UPDATE [t1] SET [t1].[CustomerID] = @2 FROM [Orders] [t1] LEFT OUTER JOIN [Customers] AS [t0] ON [t0].[CustomerID] = [t1].[CustomerID] WHERE [t0].[CustomerID] = @0; |
@0 – parametr z wartością klucza usuwanego rekordu
Wybór opcji przez użytkownika
Kolejną możliwością jest pozostawienie tego wyboru użytkownikowi.
Taka funkcja może być przydatna podczas konfigurowania/tworzenia aplikacji. Nie ma realnej przydatności w w aplikacji produkcyjnej.
Wygląd formularza wyboru opcji:
Formularz wyboru opcji jest wyświetlany kaskadowo, czyli także dla kluczy obcych powiązanej encji.
Soft delete
Soft delete jest alternatywną metodą usuwania. Gdy jest ono włączone, kaskadowe opcje dla kluczy obcych nie będą brane po uwagę. Jedyny rekord, który ulegnie zmianie będzie usuwany rekord.
Włączanie soft delete jest dwuetapowe. Najpierw ustawiamy flagę dla encji.
Fluent konfiguracja:
1 |
SoftDelete(); |
Konfiguracja atrybutami:
1 2 |
[SoftDelete] public class Customer |
Następnie ustalamy, które zmienne będą miały zmienioną wartość podczas usuwania. Możemy ustawić albo statyczną wartość, lub skorzystać z ValueBehavior . Jeśli żadna z tych ze zmiennych nie będzie ustawiona a soft delete będzie włączony wtedy będzie rzucony exception.
1 2 3 4 5 6 7 |
public enum ValueBehavior { Now, UtcNow, CurrentUserId, CurrentUserName } |
Fluent konfiguracja:
1 2 3 4 5 6 7 8 |
Property(x => x.IsDeleted, x => { x.OnDelete(value: true); }); Property(x => x.RemovedOn, x => { x.OnDelete(ValueBehavior.UtcNow); }); |
Konfiguracja atrybutami:
1 2 3 4 |
[OnDelete(value: true)] public bool IsDeleted { get; set; } [OnDelete(ValueBehavior.UtcNow)] public DateTime RemovedOn { get; set; } |
Dokładniejsze omówienie ValueBehavior będzie w jednym z przyszłych wpisów.
[…] poprzednim wpisie na temat usuwania rekordów wspomniałem o metodzie OnDelete, która ustawia wartości properties podczas […]