Pobieram dane filmu z zewnętrznego interfejsu API. W pierwszej fazie zeskrobuję każdy film i wstawię go do własnej bazy danych. W drugiej fazie będę okresowo aktualizować moją bazę danych za pomocą interfejsu API „Zmiany” interfejsu API, który mogę zapytać, aby zobaczyć, które filmy zostały zmienione.
Moja warstwa ORM to Entity-Framework. Klasa Movie wygląda następująco:
class Movie
{
public virtual ICollection<Language> SpokenLanguages { get; set; }
public virtual ICollection<Genre> Genres { get; set; }
public virtual ICollection<Keyword> Keywords { get; set; }
}
Problem pojawia się, gdy mam film, który wymaga aktualizacji: moja baza danych będzie myślała o śledzonym obiekcie, a nowy, który otrzymam z wywołania API aktualizacji, to różne obiekty, niezależnie od tego .Equals()
.
Powoduje to problem, ponieważ gdy teraz spróbuję zaktualizować bazę danych o zaktualizowany film, wstawi go zamiast aktualizować istniejący film.
Miałem już ten problem z językami i moim rozwiązaniem było wyszukiwanie załączonych obiektów językowych, odłączenie ich od kontekstu, przeniesienie ich PK do zaktualizowanego obiektu i dołączenie go do kontekstu. Kiedy SaveChanges()
jest teraz wykonywany, zasadniczo go zastąpi.
Jest to dość śmierdzące podejście, ponieważ jeśli będę kontynuować to podejście do mojego Movie
obiektu, oznacza to, że będę musiał odłączyć film, języki, gatunki i słowa kluczowe, wyszukać każdy z nich w bazie danych, przenieść ich identyfikatory i wstawić nowe obiekty.
Czy można to zrobić bardziej elegancko? Idealnie chcę po prostu przekazać zaktualizowany film do kontekstu i wybrać ten właściwy film do aktualizacji na podstawie Equals()
metody, zaktualizować wszystkie jego pola i dla każdego złożonego obiektu: ponownie użyć istniejącego rekordu na podstawie własnej Equals()
metody i wstawić, jeśli jeszcze nie istnieje.
Mogę pominąć odłączanie / dołączanie, podając .Update()
metody dla każdego złożonego obiektu, których mogę użyć w połączeniu z odzyskiwaniem wszystkich dołączonych obiektów, ale nadal będzie to wymagało ode mnie pobrania każdego istniejącego obiektu w celu jego aktualizacji.
id
a filmy z zewnętrznego interfejsu API są dopasowywane do lokalnych za pomocą pola tmdbid
. Nie mogę pobrać wszystkich elementów, które wymagają aktualizacji w jednym połączeniu, ponieważ dotyczą one filmów, gatunków, języków, słów kluczowych itp. Każdy z nich ma PK i może już istnieć w bazie danych.