W poprzednich wpisach (dotyczących scenariusza połączonego i rozłączonego) zapoznaliśmy się z różnymi metodami ustawiającymi EntityState dla danej encji. W tym wpisie poznamy sposób na śledzenie diagramu encji (TrackGraph) oraz ręcznie ustawimy odpowiedni EntityState dla każdej encji.
Metoda wspomniana w tytule wpisu: ChangeTracker.TrackGraph() została wprowadzona w Entity Framework Core w celu śledzenia diagramu encji i ustawiania niestandardowych stanów encji.
Metoda rozpoczyna śledzenie encji głównej oraz wszystkich encji podrzędnych przechodząc przez odpowiednie właściwości nawigacyjne. W przypadku wykrycia jednostki podrzędnej dochodzi do zainiciowania wywołania zwrotnego (callback), które pozwala na ustawienie odpowiedniego stanu encji. Dzięki wywołaniu zwrotnemu jesteśmy w stanie zaimplementować niestandardową logikę w celu ustawienia EntityState. Musimy jednak pamiętać o sytuacji w której żaden stan nie jest ustawiony – taka encja nie jest śledzona.
Przykład użycia metody TrackGraph omówimy na bazie poprzedniego wpisu:
var customer = new Customer() { FullName = "Paweł", Address = new Address() // encja podrzędna z wartością klucza { Id = 1, City = "Gdynia", CustomerAddress = "Port Gdynia" }, Orders = new List<Order>() { new Order() { OrderName = "Samochód"}, // encja podrzędna bez klucza new Order() { Id = 2} // encja podrzędna z wartością klucza } }; using(var context = new ApplicationDbContext()) { // zwróćcie uwagę, że nie korzystamy z dostępnych metod // od razu przechodzimy do ręcznego zarządzania context.ChangeTracker.TrackGraph(customer, e => { if(e.Entry.IsKeySet) { e.Entry.State = EntityState.Unchanged; } else { e.Entry.State = EntityState.Added; } }); CheckEntityState(context.ChangeTracker.Entries()); }
W powyższym przykładzie wykorzystujemy metodę TrackGraph() do ustawienia stanu każdej encji należącej do encji Customer. Pierwszy parametr przekazywany do metody to encja główna od której ma się rozpocząć śledzenie a drugi to delegat wywołania zwrotnego, który zostanie wykonany na każdej encji wykrytej przez rekursję. Wyrażenie lambda pozwala ustawić stan Unchanged dla jednostek, które mają prawidłowe wartości klucza oraz stan Added dla jednostek, których wartości klucza są puste. Do tego celu wykorzystujemy właściwość IsKeySet, która przyjmuje wartość true dla encji o zdefiniowanej wartości klucza.