Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Śledzenie kontroluje, czy Entity Framework Core przechowuje informacje o instancji jednostki w swoim rejestrze zmian. Jeśli jednostka jest śledzona, wszelkie zmiany wykryte w jednostce są utrwalane w bazie danych podczas SaveChanges. EF Core również poprawia właściwości nawigacyjne między encjami w wynikach zapytania z mechanizmem śledzenia oraz encjami, które są monitorowane przez mechanizm śledzenia zmian.
Uwaga / Notatka
Typy jednostek bez klucza nigdy nie są śledzone. Wszędzie tam, gdzie w tym artykule wymieniono typy jednostek, odnosi się do typów jednostek, które mają zdefiniowany klucz.
Wskazówka
Przykład z tego artykułu można zobaczyć w witrynie GitHub.
Śledzenie zapytań
Domyślnie zapytania zwracające typy jednostek są śledzone. Zapytanie śledzące oznacza, że wszelkie zmiany wystąpień jednostki są utrwalane przez SaveChanges. W poniższym przykładzie zmiana klasyfikacji blogów jest wykrywana i utrwalana w bazie danych podczas :SaveChanges
var blog = await context.Blogs.SingleOrDefaultAsync(b => b.BlogId == 1);
blog.Rating = 5;
await context.SaveChangesAsync();
Gdy wyniki są zwracane w zapytaniu śledzenia, program EF Core sprawdza, czy jednostka jest już w kontekście. Jeśli program EF Core znajdzie istniejącą jednostkę, zwracane jest to samo wystąpienie, które może potencjalnie używać mniejszej ilości pamięci i być szybsze niż zapytanie bez śledzenia. Program EF Core nie zastępuje bieżących i oryginalnych wartości właściwości jednostki we wpisie z wartościami bazy danych. Jeśli jednostka nie zostanie znaleziona w kontekście, program EF Core utworzy nowe wystąpienie jednostki i dołączy go do kontekstu. Wyniki zapytania nie zawierają żadnej jednostki, która jest dodawana do kontekstu, ale nie jest jeszcze zapisywana w bazie danych.
Zapytania bez śledzenia
Zapytania śledzenia nie są przydatne, gdy wyniki są używane w scenariuszu tylko do odczytu. Zazwyczaj są one szybsze do wykonania, ponieważ nie ma potrzeby konfigurowania informacji śledzenia zmian. Jeśli jednostki pobrane z bazy danych nie muszą być aktualizowane, należy użyć zapytania bez śledzenia. Dla pojedynczego zapytania można ustawić brak śledzenia. Zapytanie bez śledzenia daje również wyniki na podstawie tego, co znajduje się w bazie danych, pomijając wszelkie lokalne zmiany lub dodane jednostki.
var blogs = await context.Blogs
.AsNoTracking()
.ToListAsync();
Domyślne zachowanie śledzenia można zmienić na poziomie instancji kontekstu.
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var blogs = await context.Blogs.ToListAsync();
W następnej sekcji wyjaśniono, kiedy zapytanie bez śledzenia może być mniej wydajne niż zapytanie śledzenia.
Rozpoznawanie tożsamości
Ponieważ zapytanie śledzenia używa monitora zmian, program EF Core wykonuje rozpoznawanie tożsamości w zapytaniu śledzenia. Podczas materializowania obiektu, EF Core zwraca tę samą instancję obiektu z programu śledzącego zmiany, jeśli ten obiekt jest już śledzony. Jeśli wynik zawiera tę samą jednostkę wiele razy, to samo wystąpienie jest zwracane dla każdego wystąpienia. Zapytania bez śledzenia:
- Nie używaj monitora zmian i nie rób rozpoznawania tożsamości.
- Zwróć nowe wystąpienie jednostki nawet wtedy, gdy ta sama jednostka jest zawarta w wyniku wiele razy.
Śledzenie i brak śledzenia można połączyć w tym samym zapytaniu. Oznacza to, że możesz mieć zapytanie bez śledzenia, które wykonuje rozpoznawanie tożsamości w wynikach. Podobnie jak AsNoTracking operator z możliwością wykonywania zapytań dodaliśmy inny operator AsNoTrackingWithIdentityResolution<TEntity>(IQueryable<TEntity>). W wyliczeniu QueryTrackingBehavior dodano skojarzony wpis. Gdy zapytanie do używania rozpoznawania tożsamości jest skonfigurowane bez śledzenia, autonomiczny monitor zmian jest używany w tle podczas generowania wyników zapytania, więc każde wystąpienie jest zmaterializowane tylko raz. Ponieważ ten monitor zmian różni się od tego w kontekście, wyniki nie są śledzone przez kontekst. Gdy zapytanie zostanie w pełni wyliczone, śledzenie zmian wykracza poza zakres i jest usuwany przez mechanizm oczyszczania pamięci zgodnie z potrzebami.
var blogs = await context.Blogs
.AsNoTrackingWithIdentityResolution()
.ToListAsync();
Konfigurowanie domyślnego zachowania śledzenia
Jeśli zmienisz zachowanie śledzenia dla wielu zapytań, możesz zamiast tego zmienić wartość domyślną:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFQuerying.Tracking;Trusted_Connection=True;ConnectRetryCount=0")
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
}
Dzięki temu wszystkie zapytania są domyślnie bez śledzenia. Możesz nadal dodawać AsTracking , aby śledzić określone zapytania.
Śledzenie i projekcje niestandardowe
Nawet jeśli typ wyniku zapytania nie jest typem jednostki, program EF Core będzie domyślnie śledzić typy jednostek zawarte w wynikach. W poniższym zapytaniu, które zwraca typ anonimowy, w zestawie wyników będą śledzone wystąpienia elementu Blog.
var blog = context.Blogs
.Select(
b =>
new { Blog = b, PostCount = b.Posts.Count() });
Jeśli zestaw wyników zawiera typy jednostek pochodzące z kompozycji LINQ, program EF Core będzie je śledzić.
var blog = context.Blogs
.Select(
b =>
new { Blog = b, Post = b.Posts.OrderBy(p => p.Rating).LastOrDefault() });
Jeśli zestaw wyników nie zawiera żadnych typów jednostek, śledzenie nie jest wykonywane. W poniższym zapytaniu zwracamy typ anonimowy z niektórymi wartościami z jednostki (ale nie ma wystąpień rzeczywistego typu jednostki). Nie ma śledzonych jednostek wychodzących z zapytania.
var blog = context.Blogs
.Select(
b =>
new { Id = b.BlogId, b.Url });
Program EF Core umożliwia ocenę klienta w projekcji najwyższego poziomu. Jeśli program EF Core zmaterializuje wystąpienie jednostki na potrzeby oceny klienta, zostanie ono śledzone. W tym miejscu ponieważ przekazujemy blog encje do metody StandardizeURL klienta, program EF Core będzie także śledzić obiekty blogu.
var blogs = await context.Blogs
.OrderByDescending(blog => blog.Rating)
.Select(
blog => new { Id = blog.BlogId, Url = StandardizeUrl(blog) })
.ToListAsync();
public static string StandardizeUrl(Blog blog)
{
var url = blog.Url.ToLower();
if (!url.StartsWith("http://"))
{
url = string.Concat("http://", url);
}
return url;
}
Program EF Core nie śledzi wystąpień jednostek bez klucza zawartych w wyniku. Jednak program EF Core śledzi wszystkie inne wystąpienia typów jednostek z kluczem zgodnie z powyższymi regułami.
Poprzednie wersje
Przed wersją 3.0 platforma EF Core miała pewne różnice w sposobie śledzenia. Istotne różnice są następujące:
Jak wyjaśniono na stronie Ocena klienta i serwera , program EF Core obsługiwał ocenę klienta w dowolnej części zapytania przed wersją 3.0. Ocena klienta spowodowała materializację jednostek, które nie były częścią wyniku. Dlatego EF Core przeanalizował wynik, aby wykryć, co należy śledzić. Ten projekt różnił się w następujący sposób:
Ocena klienta w projekcji, która spowodowała materializację, ale nie zwróciła zmaterializowanego wystąpienia jednostki, nie została śledzona. Poniższy przykład nie śledził
blogjednostek.var blogs = await context.Blogs .OrderByDescending(blog => blog.Rating) .Select( blog => new { Id = blog.BlogId, Url = StandardizeUrl(blog) }) .ToListAsync();Program EF Core nie śledził obiektów wychodzących z kompozycji LINQ w niektórych przypadkach. Poniższy przykład nie śledził
Post.var blog = context.Blogs .Select( b => new { Blog = b, Post = b.Posts.OrderBy(p => p.Rating).LastOrDefault() });
Za każdym razem, gdy wyniki zapytania zawierały typy jednostek bez klucza, całe zapytanie stało się nieśledzące. Oznacza to, że typy jednostek z kluczami, które były częścią wyników, również nie były śledzone.
Program EF Core służy do rozwiązywania problemów z tożsamościami w zapytaniach bez śledzenia. Użyto słabych referencji, aby śledzić obiekty, które zostały już zwrócone. Dlatego jeśli zestaw wyników zawiera tę samą jednostkę wiele razy, otrzymasz to samo wystąpienie dla każdego wystąpienia. Chociaż jeśli poprzedni wynik z tą samą tożsamością wyszedł z zakresu i odebrano śmieci, program EF Core zwrócił nowe wystąpienie.