Stany obiektów i śledzenie zmian
Obiekty LINQ to SQL zawsze uczestniczą w pewnym stanie. Na przykład gdy linQ to SQL tworzy nowy obiekt, obiekt jest w Unchanged
stanie. Nowy obiekt, który samodzielnie tworzysz, jest nieznany DataContext samodzielnie i jest w Untracked
stanie . Po pomyślnym wykonaniu SubmitChangespolecenia wszystkie obiekty znane LINQ to SQL są w Unchanged
stanie. (Pojedynczy wyjątek jest reprezentowany przez te, które zostały pomyślnie usunięte z bazy danych, które są w Deleted
stanie i są bezużyteczne w tym DataContext wystąpieniu).
Stany obiektów
W poniższej tabeli wymieniono możliwe stany obiektów LINQ to SQL.
Stan | opis |
---|---|
Untracked |
Obiekt, który nie jest śledzony przez LINQ to SQL. Oto kilka przykładów: — Obiekt nie jest odpytywane za pośrednictwem bieżącego DataContext (na przykład nowo utworzonego obiektu). - Obiekt utworzony za pomocą deserializacji — Obiekt, którego dotyczy zapytanie, za pomocą innego DataContextobiektu . |
Unchanged |
Obiekt pobrany przy użyciu bieżącego DataContext i nie wiadomo, że został zmodyfikowany od czasu jego utworzenia. |
PossiblyModified |
Obiekt dołączony do obiektu DataContext. Aby uzyskać więcej informacji, zobacz Pobieranie danych i operacje CUD w aplikacjach N-warstwowych (LINQ to SQL). |
ToBeInserted |
Obiekt nie został pobrany przy użyciu bieżącego DataContextobiektu . Powoduje to, że baza danych INSERT podczas SubmitChangesprogramu . |
ToBeUpdated |
Obiekt znany z modyfikacji od czasu jego pobrania. Powoduje to, że baza danych UPDATE podczas SubmitChangesprogramu . |
ToBeDeleted |
Obiekt oznaczony do usunięcia, powodując bazę danych DELETE podczas .SubmitChanges |
Deleted |
Obiekt, który został usunięty w bazie danych. Ten stan jest końcowy i nie zezwala na dodatkowe przejścia. |
Wstawianie obiektów
Możesz jawnie zażądać Inserts
za pomocą polecenia InsertOnSubmit. Alternatywnie linQ to SQL może wywnioskować Inserts
, wyszukując obiekty połączone z jednym ze znanych obiektów, które muszą zostać zaktualizowane. Jeśli na przykład dodasz Untracked
obiekt do EntitySet<TEntity> obiektu lub ustawisz EntityRef<TEntity> go na Untracked
obiekt, obiekt Untracked
będzie osiągalny za pomocą śledzonych obiektów na grafie. Podczas przetwarzania SubmitChangesfunkcja LINQ to SQL przechodzi przez śledzone obiekty i odnajduje wszelkie osiągalne trwałe obiekty, które nie są śledzone. Takie obiekty są kandydatami do wstawiania do bazy danych.
W przypadku klas w hierarchii dziedziczenia InsertOnSubmit(o
) ustawia również wartość elementu członkowskiego wyznaczonego jako dyskryminujący , aby dopasować typ obiektu o
. W przypadku typu zgodnego z domyślną wartością dyskryminującą ta akcja powoduje zastąpienie wartości dyskryminującej wartością domyślną. Aby uzyskać więcej informacji, zobacz Obsługa dziedziczenia.
Ważne
Obiekt dodany do obiektu Table
nie znajduje się w pamięci podręcznej tożsamości. Pamięć podręczna tożsamości odzwierciedla tylko to, co jest pobierane z bazy danych. Po wywołaniu metody InsertOnSubmit, dodana jednostka nie jest wyświetlana w zapytaniach względem bazy danych do momentu SubmitChanges pomyślnego ukończenia.
Usuwanie obiektów
Oznaczasz śledzony obiekt o
do usunięcia przez wywołanie DeleteOnSubmitmetody (o) dla odpowiedniego Table<TEntity>elementu . LinQ to SQL uwzględnia usunięcie obiektu z EntitySet<TEntity> operacji aktualizacji, a odpowiadająca mu wartość klucza obcego ma wartość null. Element docelowy operacji (o
) nie jest usuwany z jej tabeli. Na przykład cust.Orders.DeleteOnSubmit(ord)
wskazuje aktualizację, w której relacja między cust
i ord
jest zerwana przez ustawienie klucza ord.CustomerID
obcego na null. Nie powoduje to usunięcia wiersza odpowiadającego .ord
LINQ to SQL wykonuje następujące przetwarzanie po usunięciu obiektu (DeleteOnSubmit) z jego tabeli:
Po SubmitChanges wywołaniu jest wykonywana
DELETE
operacja dla tego obiektu.Usunięcie nie jest propagowane do powiązanych obiektów niezależnie od tego, czy są ładowane. W szczególności powiązane obiekty nie są ładowane do aktualizowania właściwości relacji.
Po pomyślnym wykonaniu SubmitChangesobiektu obiekty są ustawione na
Deleted
stan . W związku z tym nie można użyć obiektu ani jegoid
obiektu w tym DataContextobiekcie . Wewnętrzna pamięć podręczna przechowywana przez DataContext wystąpienie nie eliminuje obiektów, które są pobierane lub dodawane jako nowe, nawet po usunięciu obiektów w bazie danych.
Można wywołać DeleteOnSubmit tylko dla obiektu śledzonego przez DataContextobiekt . W przypadku obiektu należy wywołać metodę Untracked
Attach przed wywołaniem metody DeleteOnSubmit. Wywołanie DeleteOnSubmit obiektu Untracked
zgłasza wyjątek.
Uwaga
Usunięcie obiektu z tabeli informuje LINQ to SQL o wygenerowaniu odpowiedniego polecenia SQL DELETE
w czasie SubmitChanges. Ta akcja nie powoduje usunięcia obiektu z pamięci podręcznej ani propagowania usuwania do powiązanych obiektów.
Aby odzyskać id
usunięty obiekt, użyj nowego DataContext wystąpienia. W celu oczyszczenia powiązanych obiektów można użyć funkcji usuwania kaskadowego bazy danych lub ręcznie usunąć powiązane obiekty.
Powiązane obiekty nie muszą być usuwane w żadnej specjalnej kolejności (w przeciwieństwie do bazy danych).
Aktualizowanie obiektów
Możesz wykryć Updates
, obserwując powiadomienia o zmianach. Powiadomienia są dostarczane za pośrednictwem PropertyChanging zdarzenia w programach ustawiających właściwości. Gdy funkcja LINQ to SQL jest powiadamiana o pierwszej zmianie obiektu, tworzy kopię obiektu i traktuje obiekt jako kandydata do wygenerowania Update
instrukcji.
W przypadku obiektów, które nie implementują INotifyPropertyChangingprogramu , LINQ to SQL przechowuje kopię wartości, które miały obiekty, gdy zostały one po raz pierwszy zmaterializowane. Podczas wywoływania metody SubmitChangesfunkcja LINQ to SQL porównuje bieżące i oryginalne wartości, aby zdecydować, czy obiekt został zmieniony.
W przypadku aktualizacji relacji odwołanie od elementu podrzędnego do elementu nadrzędnego (czyli odwołanie odpowiadające kluczowi obcemu) jest uznawane za urząd. Odwołanie w odwrotnym kierunku (czyli od elementu nadrzędnego do elementu podrzędnego) jest opcjonalne. Klasy relacji (EntitySet<TEntity> i EntityRef<TEntity>) gwarantują, że odwołania dwukierunkowe są spójne dla relacji jeden do wielu i jeden do jednego. Jeśli model obiektów nie używa elementu EntitySet<TEntity> lub EntityRef<TEntity>, a jeśli odwołanie odwrotne jest obecne, twoim obowiązkiem jest zachowanie spójności z odwołaniem do przodu po zaktualizowaniu relacji.
Jeśli zaktualizujesz zarówno wymagane odwołanie, jak i odpowiadający mu klucz obcy, upewnij się, że się zgadzają. Wyjątek InvalidOperationException jest zgłaszany, jeśli te dwa nie są synchronizowane w momencie wywołania metody SubmitChanges. Mimo że zmiany wartości klucza obcego są wystarczające do wpływu na aktualizację bazowego wiersza, należy zmienić odwołanie, aby zachować łączność grafu obiektu i dwukierunkową spójność relacji.