Update, Attach, SaveChanges i inne składniki EntityFrameworka

Wprowadzenie

Pracując z Entity Framework możemy doceniać jego moc oraz zapomnieć o tym, jaką potężną magią on operuje. Np. skąd ten diabeł wie, co się zmieniło, a kiedy muszę mu o tym przypomnieć.

Mam prostą regułę w głowie, jeśli wyciągam dane z kontekstu i zaraz od razu wrzucam je tam z powrotem, nie ustawiam do tego flag, nie wtrącam się, nie robię hokus-pokus i zakładam, że wszystko będzie dobrze.

Jeśli wyciągam dane na dłużej, wtedy podpowiadam EF, żeby nie śledził zmian, bo to trochę zajmie, zanim te dane wrócą do bazy danych i szkoda zachodu.

Dane można zapisać / zaktualizować na kilka sposobów:

Na raz:

  • Pobierz
  • Zmodyfikuj
  • Zapisz

Na dwa

  • Utwórz
  • Przypnij
  • Zapisz

Na trzy:

  • Nie zaglądam, jeśli działa u Ciebie to dawaj dawaj na produkcje 😉

Wygląda że proste? To sprawdzam, co i jak zadziała

W obu przypadkach mam taki oto kod:

Nie oszukujmy się, bunkrów nie ma, kontekst oraz jakiś POCO na potrzeby przykładów.

Uno

Ten przykład działa, pobieram, modyfikuje, zapisuje. EF robi magię i potrafi sam wykryć zmianę w encji – nie wymaga wywołania `update` aby znaleźć i nanieść zmiany na obiekcie. PFM! Wymagany jest natomiast strzał do bazy aby pobrać początkowy obiekt do modyfikacji.
Na plus – nie tracę informacji, który nie modyfikuje. Wrócę do tego niżej.

Duo(s)

Teraz się zacznie, co się stanie, gdy wyciągnę dane bez śledzenia i zapiszę zamiany:

Pudło! Nic, EF cichutko “zapisał” zmienione encje, ale mój odcięty obiekt nie był na tej liście, w związku z tym – nic się nie wydarzyło. Może tylko odrobina smutku. Ale sam tego chciałem, przecież mówiłem – bez śledzenia!

Spróbuje inaczej, stworze nowy obiekt, przypnę go do kontekstu i wtedy zapisze:

Hus! (Dzięki panie Łukaszu) – nie działa! Ale czemu? Przecież obiekt jest w kontekście!

Ach, obiekt został dodany, ale jest oznaczony jako unchanged! Ok-sprawdzam:

Czyli co, nawet jeśli mam nowy obiekt i przypiąłem go do kontekstu nadal nie jest śledzony? Nie koniecznie, obiekt został przypięty i jest śledzony, ale zmiany nie nastąpiły po włączeniu śledzenia. Natomiast taki kod:

Robi już robotę, zwróć uwagę, że zmiany następują po przypięci i włączeniu śledzenia zmian

Zamiast takiego cyrkolenia się, można iść na skróty i wywołać po prostu Update:

Który ustawia status obiektu na modified i zapisuje zmiany.

Turbo mega uwaga:
Oba przypadku zerują wartość dla ReleaseDate który dostanie domyślną 01.01.0001 00:00:00 wartość-trzeba tego pilnować. W przypadku gdy wcześniej ładujemy obiekt z DB a potem go modyfikujemy, ReleaseDate jest ustawiony i nie nadpisany zerową wartością.
Pewnie można by poszukać i podpowiedzieć, które właściwości zostały zmienione, ale to wymagałoby znajomości voodoo.

Dodam tylko dla optymalizacji, że gdy wyciągamy obiekt z EF, który nie będzie zmieniany, np. tylko żeby wyciągnąć i wyświetlić, warto użyć opcji `
AsNoTracking, aby podpowiedzieć EF zaprzestania śledzenia obiektów, bo zniknąć one z naszego kontekstu.

Jeśli zaistnieje potrzeba ponownego podpięcia, można zrobić attach lub update – ale to już wiesz.

 

Szczegóły tutej:
https://learn.microsoft.com/en-us/ef/core/change-tracking/

ps.
Tak naprawdę to nie korzystam z EF.

ps2.
Źródło całego pliku cs dostępne tutaj:
https://gist.github.com/jstadnicki/9a97619c26e4ba9571fa2aec40be25d3

Czekoladka zamiast pudełka

Czekoladka zamiast pudełka

Może jednak, obok. Nie róbmy dramy.

Skąd to się wzięło

Mam swój zestaw narzędzi, z którym jestem w stałym związku; total commander, notepad2, cmder czy dużo dużo innych. Po świeżej instalacji systemu pierwsze co instalowałem to dropbox, zaciągały się dokumenty oraz folder tools gdzie 99% moich narzędzi czekało aż będę z nich korzystać. Wyżej wymienione trzy to tylko czubek góry lodowej, oczywiście czasem jedne znikały, inne dochodziły, tendencja jednak była wzrostowa.
Z czasem dropbox zaczął mnie męczyć informacją o tym, że w zasadzie mógłbym się zainteresować kontem premium. Cebyla jest we mnie silna, wyczyściłem folder tools, wyczyściłem inne i jeszcze chwilę czasu miałem.

Continue reading

Singleton – wzorzec Schrödingera

Na dwoje babka wróżyła

Czarna owca wśród wzorców projektowych – singleton. Często nazywany antywzorcem – źle. Trochę źle. Singleton w zależności od tego jak będzie używany będzie wykazywać cechy wzorca lub antywzorca.

Antywzorzec

Singleton jako zmienna globalnie dostępna, każdy może do niego sięgnąć i korzystać. Inny, bardziej obiektowy sposób na statyczne/globalne zmienne.

Wzorzec

Continue reading

ITAN – projekt rusza razem z #dajsiepoznac

Is There Any News

Jest to plan na internetową aplikacją do czytania kanałów RSS. Chodziło mi to po głowie już jakiś czas, kiedyś sprzedałem ten pomysł studentom, z którymi miałem okazję się współpracować. Sam pomysł wydaje się być prosty, dlatego ja zamierzam dołożyć do tego kilka dodatkowych rzeczy. Wymarzyłem sobie, że każdy użytkownik będzie mógł poza kanałami RSS obserwować także innych użytkowników. W ten sposób można poznać, jakie kanały czytają inni, które wpisy czytają dokładniej i czy  klikają po pełną treść. Podobnie marzy mi się, aby na takiej podstawie generować podsumowania dnia, miesiąca, tygodnia. Takie najgorętsze informacje. W ten sposób nie trzeba śledzić wszystkiego, a tylko te które inni czytają, udostępniają lub komentują. Jeśli wydaje Ci się to proste spójrz na dół strony, to tylko część rzeczy, które wymyśliłem do tej pory.

Jak zebrać pomysły

Jeśli macie ta przyjemność planowania czegoś, zbierania pomysłów, głębokiej rozkminy, co, gdzie, jak z kim to szczerze polecam mind mapping. Znowu product placement i znów android: ja aktualnie korzystam z SimpleMind dla androida. Wersja podstawowa ma wszystko, wersja płatna umożliwia synchronizacje w chmurze i eksport do obrazków i innego (30pln).

Dlaczego mind mapping? Dla mnie to co jest świetną sprawą to możliwość skakania po pomysłach i dopisywanie każdego kolejnego tam gdzie czuje że będzie pasować. Nie piszę ich jeden pod drugim, mogę rzucić gdzieś na ekranie, a potem powoli łączyć jeden z drugim, aż całość stanie się spójna. Lub zacząć od ogólnego planu i potem skupiać się i wymyślać do dalej, dodawać nowe zabawki.
Z mapowania korzystam także podczas robienia notatek ze spotkania, przygotowywania prezentacji, czy szkoleń i warsztatów. Takie surowe myśli mogę potem przejrzeć,poprawić i połączyć ze sobą.

Mind map ITAN

Poniżej moja wizja na to jak i co ma robić ITAN (ach, taka piękna nazwa robocza)

ITAM mapa myśli

Zadania

Co dalej? Zapewne przetłumaczę na małe zadania i przepiszę to wszystko na odpowiednie pojedyncze zadania na trello, aby móc śledzić na bieżąco swój postęp prac. Trello to świetna i darmowa (pewnie z ograniczeniami?) internetowa tablica kanbanowa. Tworzy się kolejne tablice/projekty na nich odpowiednie kolumny i zadania. Potem wystarczy tylko robić i przeciągać w trakcie postępowania prac na projektem. Tablica ITAN dostępna jest po tym adresem: https://trello.com/b/ONqNYIcH/itan W momencie pisania posta nie ma tam nic, poza zdefiniowanymi kolumnami.

Źródła

Githuba nie muszę raczej nikomu przedstawiać. Znowu idąc na skróty, źródła dostępne będą pod tym linkiem https://github.com/jstadnicki/isthereanynews

Tyle, powodzenia i do roboty.

Code coverage bywa zdradliwy

Od kilku dni wdrażam w życie dopisanie testów do strony nad którą pracuje, bo lepiej późno niż wcale. W zabawie tej korzystam z dodatkowego narzędzia jakim jest ncrunch. Trochę więcej o nim na blogach Paweł i Arek Bardzo ciekawa sprawa, ale warto mieć dobry sprzęt, aby w pełni korzystać ze wszystkich funkcjonalności. Mi do gustu przypadła funkcjonalność mierzenia pokrycia kodu testami. Pomyślałem sobie – “spoko“, nie będę się musiał martwić, czy mam wszystko przetestowane – i właśnie o tej pułapce parę słów. Załóżmy taki kod, który będzie zmanipulowany na potrzeby przykładu:

public class UnderTest
    {
        private int someInternalVariable;
        public void Foo(int a)
        {
            if (a == 1 || a == 3)
            {
                this.someInternalVariable = a;
            }
        }
    }

A następnie taki test, który sprawdza czy zmienna została przypisana

[TestFixture]
    public class Test
    {
        [Test]
        public void T001()
        {
            var sut = new UnderTest();
            sut.Foo(5);
            Assert.AreEqual(0, sut.SomeVariable);
        }

        [Test]
        public void T001_With_Params()
        {
            var sut = new UnderTest();
            sut.Foo(1);
            Assert.AreEqual(1, sut.SomeVariable);
        }
    }

Patrząc teraz na metryki, wynik cieszy oko i aż prosi żeby pochwalić się światu, że testy mamy w jednym palcu, architektura u nas to kozak, bo właśnie wykręciliśmy 100% pokrycia kodu. Aaale potem kątem oka dostrzegamy pułapkę! O nie, a co z przypadkiem gdy a będzie 3, przecież nie mamy takiego testu – jak to możliwe, skoro cyferki mówią 100%, a serce mówi że brakuje. No tak dzieci, bo musicie pamiętać, że code coverage bywa zdradliwy i nigdy, przenigdy nie powinno się tylko na nim opierać wyników naszego testowania. . A to że kusi, to że menagierowie mówią i chcą żeby było przynajmniej 100/80/60/x procent to wiecie, oni są pragnienie, to my jesteśmy oranżada.