2013-03-11 7 views
9

Przeczytałem kilka artykułów (article1, article2) o Entity Framework, które wiele razy wywołuje funkcję DetectChanges, co czyni ją bardzo powolną podczas pracy z dużymi ilościami danych.Kod EF Po pierwsze: czy można wywołać funkcję DetectChanges tuż przed zmianami SaveChanges?

Czy mogę, na przykład, wyłączyć autoDetectChanges, gdy inicjuję kontekst, i po prostu zadzwonić pod numer DetectChanges(), zanim zadzwonię pod numer .SaveChanges()?

Czy kontekst rozpoznaje wstawione/zmienione/usunięte obiekty?

var _dbContext = new ProjectContext(); 
_dbContext.Configuration.AutoDetectChangesEnabled = false; 

// add/edit/delete entities 

_dbContext.ChangeTracker.DetectChanges(); 
_dbContext.SaveChanges(); 

Czy to podejście działa? lub może tworzyć ukryte błędy?

+0

Nie jestem w 100% pewny, czy robi coś dziwnego w tle, ale ja stosowałem podobne podejście, nie znajdując żadnych złych efektów ubocznych. – Thewads

Odpowiedz

16

Arthur Vickers definiuje reguły kiedy DetectChanges nie musi być wywołana (nawet nie przed SaveChanges) in this blog post:

Nie wywołanie kodu EF pozostawi kontekst, w stanie, w którym DetectChanges musi być wywołana jeśli wcześniej nie trzeba było nazywać się .

chodzi Dodaj i Usuń są „Kod EF” Metody bo albo zadzwonić Add lub Delete lub ustawić stan context.Entry(entity).State do Added lub Deleted. Tak więc, jeśli po prostu przeszukasz kilka obiektów i dodasz je lub usuniesz, nie musisz w ogóle dzwonić pod numer DetectChanges.

Jeśli chodzi o Edycja jest, jak sądzę, nieco bardziej subtelna. Podczas aktualizacji jednostek za pomocą jednej ...

context.Entry(entity).CurrentValues.SetValues(someObject); 

... lub za pomocą właściwości API DbContext ...

context.Entry(entity).Property(e => e.SomeProperty).CurrentValue = someValue; 

... wtedy nie trzeba DetectChanges (nawet nie przed SaveChanges), ponieważ są one ponownie wywoływane w "Kodzie EF".

Jeśli wystarczy zmienić wartości właściwości podmiotu podobnego ...

entity.SomeProperty = someValue; 

... potem druga reguła in the same blog post powiązany powyżej dotyczy:

dowolnym momencie, że non-EF zmiany kodu dowolna wartość właściwości obiektu lub obiektu złożonego , a następnie DetectChanges może wymagać wywołania.

I myślę, że trzeba w rzeczywistości tylko jeden wezwanie do DetectChanges przed SaveChangesjeżeli po prostu pętli przez kilka podmiotów, załadować je do lub dołączyć je do kontekstu i zmienić trochę (skalarne i kompleks) wartości nieruchomości .

Jeśli robisz bardziej skomplikowane rzeczy (może zmiany relacji? Lub coś innego?) Twoje podejście może nie być bezpieczne, ponieważ już

  1. AutoDetectChanges nie byłyby realizowane w drodze to jest i nazywa się w wielu metod EF jeśli byłoby to konieczne tylko raz tuż przed SaveChanges

  2. jest ona wymieniona in the same blog post jeszcze, że

    Jeśli kod powoduje zmiany zmiany właściwości jednostek zamiast po prostu wywołanie Dodaj lub Dołącz, a następnie, przez zasadą 2, DetectChanges będzie musiał zostać wywołany, co najmniej jako część SaveChanges i ewentualnie również przed.

    (Podświetlanie ode mnie)

Niestety nie wiem przykład kodu, który będzie pokazać podczas wywoływania DetectChanges na wcześniejszych etapach niż tuż przed SaveChanges jest konieczne. Ale z uwagi na punkt 1 powyżej jestem pewien, że takie przykłady istnieją.

+0

To był świetny wpis, dziękuję. Ale jestem trochę niejasny (przepraszam za to): 1. Dlaczego EF musi wywoływać DetectChanges tyle razy, kiedy mógł po prostu wywołać DetectChanges przed faktycznym zapisaniem do bazy danych? 2. Używam obiektów 'POCO' o normalnych właściwościach (nie oznaczonych' virtual'). Kiedy zmieniam wartości właściwości obiektu, czy EF wywołuje funkcję DetectChanges() w trybie cichym? – Catalin

+0

@RaraituL: Do punktu 1: Nie wiem. To właśnie miałem na myśli moim ostatnim zdaniem. Do punktu 2: Nie. 'DetectChanges' jest wywoływany później w' SaveChanges' i garstce innych metod EF, a nie przy przypisywaniu wartości właściwości. Opcja "DetectChanges" porównuje następnie bieżące wartości właściwości z wartościami pierwotnymi (które są przechowywane jako "migawka" w kontekście obiektu), a jeśli wartości zostały zmienione, właściwości zostaną oznaczone jako zmodyfikowane. Nazywa się to "śledzeniem zmiany opartym na migawce". – Slauma

-2

Jednym z głównych problemów, które mogą być rozwiązane przez DetectChanges jest utrwalanie danych w EF, gdy mamy relację ManyToMany i.

Powiązane problemy