Udostępnij za pośrednictwem


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 jego id 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ę UntrackedAttach 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.

Zobacz też