Czy ktoś ma sugestie dotyczące najbardziej efektywnego sposobu implementacji logiki „zaktualizuj wiersz, jeśli istnieje”, wstaw „logikę” za pomocą Entity Framework?
c#
entity-framework
Jonathan Wood
źródło
źródło
Odpowiedzi:
Jeśli pracujesz z dołączonym obiektem (obiekt załadowany z tej samej instancji kontekstu), możesz po prostu użyć:
Jeśli możesz skorzystać z wiedzy na temat klucza obiektu, możesz użyć czegoś takiego:
Jeśli nie możesz zdecydować o istnieniu obiektu na podstawie jego identyfikatora, musisz sprawdzić zapytanie:
źródło
using
bloku. Czy można pozostawić kontekst na chwilę w pamięci? Na przykład za życia formularza Windows? Zwykle próbuję wyczyścić obiekty bazy danych, aby zapewnić minimalne obciążenie bazy danych. Czy nie ma problemu czekającego na zniszczenie mojego kontekstu EF?Począwszy od Entity Framework 4.3,
AddOrUpdate
w przestrzeni nazw istnieje metodaSystem.Data.Entity.Migrations
:który przez doktora :
Aby odpowiedzieć na komentarz @ Smashing1978 , wkleję odpowiednie części z linku dostarczonego przez @Colin
To powiedziawszy, mam sytuację, w której pobieram dane z usługi zewnętrznej i wstawiam lub aktualizuję istniejące wartości za pomocą klucza podstawowego (a moje lokalne dane dla konsumentów są tylko do odczytu) - używam
AddOrUpdate
w produkcji od ponad 6 miesięcy i tak dalej zdecydowanie nie ma problemów.źródło
Magia dzieje się podczas dzwonienia
SaveChanges()
i zależy od prąduEntityState
. Jeśli jednostka maEntityState.Added
, zostanie dodana do bazy danych, jeśli takEntityState.Modified
, zostanie zaktualizowana w bazie danych. Możesz więc zaimplementowaćInsertOrUpdate()
metodę w następujący sposób:Więcej informacji o EntityState
Jeśli nie możesz sprawdzić,
Id = 0
czy jest to nowy podmiot, czy nie, sprawdź odpowiedź Ladislava Mrnka .źródło
Jeśli wiesz, że używasz tego samego kontekstu i nie odłączasz żadnych bytów, możesz utworzyć ogólną wersję, taką jak ta:
db
może oczywiście być polem klasy lub metoda może być statyczna i być rozszerzeniem, ale to jest podstawa.źródło
Odpowiedź Ladislava była bliska, ale musiałem wprowadzić kilka modyfikacji, aby działało to w EF6 (najpierw baza danych). Rozszerzyłem kontekst danych za pomocą metody AddOrUpdate i do tej pory wydaje się, że działa ona dobrze z odłączonymi obiektami:
źródło
Moim zdaniem warto powiedzieć, że dzięki nowo wydanemu kodowi EntityGraphOperations dla Entity Framework Code Najpierw możesz zaoszczędzić sobie przed pisaniem powtarzalnych kodów do definiowania stanów wszystkich encji na wykresie. Jestem autorem tego produktu. I opublikowałem go w githubie , projekcie kodu ( zawiera demonstrację krok po kroku i przykładowy projekt jest gotowy do pobrania) i nuget .
Będzie on automatycznie ustawiony stan podmiotów do
Added
lubModified
. I ręcznie wybierzesz, które elementy należy usunąć, jeśli już nie istnieją.Przykład:
Powiedzmy, że mam
Person
przedmiot.Person
może mieć wiele telefonów, dokument i może mieć małżonka.Chcę określić stan wszystkich jednostek, które są uwzględnione na wykresie.
Jak wiadomo, unikalne właściwości klucza mogą odgrywać rolę podczas definiowania stanu bytu telefonu. Do takich specjalnych celów mamy
ExtendedEntityTypeConfiguration<>
klasę, która dziedziczyEntityTypeConfiguration<>
. Jeśli chcemy użyć takich specjalnych konfiguracji, musimy odziedziczyć nasze klasy mapowaniaExtendedEntityTypeConfiguration<>
zamiastEntityTypeConfiguration<>
. Na przykład:To wszystko.
źródło
Wstaw inną aktualizację obu
źródło
Sprawdź istniejący wiersz za pomocą Any.
źródło
Alternatywa dla odpowiedzi @LadislavMrnka. Ma to miejsce w przypadku Entity Framework 6.2.0.
Jeśli masz konkretny
DbSet
element, który należy zaktualizować lub utworzyć:Można to jednak również wykorzystać w przypadku
DbSet
klucza ogólnego z pojedynczym kluczem podstawowym lub złożonym kluczem podstawowym.źródło
Poprawione
źródło