Historia

Zanim przejdziemy do interesujących zagadnień związanych z EF Core przeniesiemy się na chwilę w przeszłość. Spojrzymy na ewolucję platformy, poznamy podstawy mapowania obiektowo-relacyjnego (ORM) oraz zapoznamy się z podstawowym działaniem frameworka.

Przed pojawieniem się .NET 3.5 pobieranie i zapisywanie danych odbywało się głównie przy pomocy ADO.NET oraz Enterprise Data Access Block. Drugie rozwiązanie, zapewnie mniej znane, było głównie używane w celu obsługi podstawowych operacji CRUD na bazie danych. Mała złożoność wpływała również na niezłą wydajność.

Z drugiej strony do naszej dyspozycji zostało oddane ADO.NET. Kontrola (w dosłownym tego słowa znaczeniu) nad tworzonymi zapytaniami pozwalała na rozwiązywanie nawet najbardziej skomplikowanych problemów. Wiązało się to oczywiście z dodatkową złożonością i ryzkiem wystąpienia błędu – takie jednak są aplikacje Enterprise.

W obu przypadkach zasada działania była jednak podobna. Otwieraliśmy połączenie z bazą danych, tworzyliśmy DataSet w celu pobrania lub przesłania danych do bazy danych, konwertowaliśmy dane z ‘datasetów’ na obiekty w .NET i odwrotnie. Był to uciążliwy i podatny na błędy proces. Entity Framework to rozwiązanie powstałe w celu zautomatyzowania wszystkich powyższych działań związanych z obsługą bazy danych dla tworzonej aplikacji.

Framework pozwala na pracę z danymi przy użyciu obiektów klas bez potrzeby skupiania się bazowych tabelach i kolumnach bazy danych w której te dane są przechowywane. Dzięki takiemu rozwiązaniu programiści mogą pracować na wyższym poziomie abstrakcji skupiając się na tworzeniu aplikacji z mniejszą ilością kodu, które w efekcie są łatwiejsze w zarządzaniu. W takim rozwiązaniu eliminujemy większość kodu związanego z dostępem do danych.

EF w naszej aplikacji

Spójrzcie na poniższy diagram: Entity Framework jako warstwa aplikacji

Główną informacją płynącą z powyższego schematu jest fakt, że EF jest warstwą pomiędzy logiką biznesową aplikacji a bazą danych. Warstwa ta zapisuje dane przetwarzane przez logikę biznesową aplikacji oraz pozwala na pobieranie tych danych z bazy danych i automatyczną konwersję na obiekty zdefiniowane w logice biznesowej naszej aplikacji. Jeżeli ostatnie zdanie nie jest dla Was w pełni zrozumiałe (nie mieliście styczności z EF) – nie martwcie się, w praktycznej części tego cyklu od razu zrozumiecie co miałem na myśli pisząc to zdanie.

Główne funkcje frameworka

  • Wieloplatformowość: w przypadku EF Core otrzymujemy wsparcie dla Windows, Linux oraz Mac. Nie możemy zapominać, że wieloplatformowość nie dotyczy EF 6 - tutaj wsparcie ogranicza się jedynie do systemu Windows;
  • Modelowanie: EF tworzy model danych encji (Entity Data Model) w oparciu o obiekty POCO (Plain Old CLR Object) z właściwościami get/set dla różnych typów danych. Model ten jest używany podczas pobierania oraz zapisywania danych w bazie danych;
  • Zapytania do bazy danych: EF pozwala na użycie zapytań LINQ do pobierania danych z bazy danych. Zapytania LINQ "przerabiane" są na język zapytań specyficzny dla danej bazy danych. Możemy również wykorzystać nieprzetworzone zapytania SQL;
  • Śledzenie zmian: EF śledzi zmiany na instancjach naszych encji. W prostych słowach: pobranie specyficznego rekordu, aktualizacja danych po stronie kodu, zapisanie (aktualizacja) danych w bazie danych przy pomocy polecenia SaveChanges(). Takie zachowanie jest domyślnie włączone. Śledzenie zmian możemy wyłączyć przy użyciu AsNoTracking() - przypadek taki jest zalecany w scenariuszu read-only i wpływa na szybkość wykonywania zapytań;
  • Zapisywanie zmian: polecenia INSERT, UPDATE oraz DELETE wykonywane są na podstawie zmian dokonanych w encjach, które nastąpiły przed wywołaniem metody SaveChanges(). EF udostępnia również asynchroniczną metodę zapisu SaveChangesAsync();
  • Współbieżność: EF wykorzystuje domyślnie optymistyczną współbieżność (Optymistic Concurrency) w celu ochrony nadpisywania zmian dokonanych przez innego użytkownika od momentu pobrania danych z bazy danych;
  • Transakcyjność: EF zarządza transakcjami w sposób automatyczny. Pozwala również na konfigurację i dopasowanie do własnych potrzeb;
  • Caching (buforowanie): EF został wyposażony w pierwszy poziom cachowania - często potwarzające się zapytania zwrócą wyniki z bufora a nie dodatkowego zapytania do bazy danych;
  • Wbudowane konwencje: zestaw domyślnych reguł automatycznie konfigurujących model EF;
  • Opcje koniguracyjne: możliwość wykorzystania atrybutów adnotacji (data annotations) lub Fluent API w celu nadpisania domyślnych reguł;
  • Migracje: tworzenie lub zarządzanie schematem bazy danych jest możliwe przy pomocy dostarczonego przez EF zestawu poleceń. Możemy wykorzystać NuGet Package Manager Console lub interfejs linii poleceń.

Zrozumieć działanie EF

Ostatni krok we wprowadzeniu to zrozumienie "tego co dzieje się pod spodem". To krótkie wyjaśnienie pozwoli Wam zrozumieć jakie etapy są niezbedę do przeprowadzania pomyślnej operacji na bazie danych. Przykład będzie bazował na podstawowych operacjach CRUD.

  1. Pierwszy krok to zdefiniowanie modelu. Proces ten obejmuje zdefiniowanie klas domeny, klasy kontekstowej wywodzącej się z DbContext oraz konfiguracji (jeżeli istnieje). EF będzie wykonywał operacje CRUD w oparciu o utworzony model.
  2. Wstawianie obiektu do bazy danych polega na dodaniu obiektu do kontekstu i wywołaniu metody SaveChanges(). Pod spodem EF utworzy odpowiednią komendę INSERT i wykona ją na bazie danych.
  3. Odczyt danych polega na wykonaniu zapytania LINQ (lub jak wcześniej wspomniałem zapytania z nieprzetworzonym SQL). W kolejnym kroku EF skonwertuje zapytanie do zapytania SQL dla wskazanej bazy danych i je wykonana. Wynik zostanie przekształcony na obiekty domenowe (encje), przetworzony przez logikę biznesową i wyświetlony użytkownikowi w określonej przez programistę formie.
  4. Usunięcie lub modyfikacja danych polega na aktualizacji kontekstu i wywołaniu metody SaveChanges(). EF utworzy odpowiednie polecenie UPDATE lub DELETE i wykona je na określonej bazie danych.

Podsumowanie

Krótkie wyjaśnienia dla osób początkujących (żeby nie wprowadzać niepotrzebnego zamieszania) oraz dla osób nieco bardziej zaawansowanych (żeby nie zastanawiały się "co on tutaj wypisuje").

W pierwszym kroku napisałem o zdefiniowaniu modelu. Musimy pamiętać, że EF pozwala na dwa podejścia: w pierwszym zaczynamy od projektu bazy danych a modele utworzone są automatycznie przez EF. Drugi sposób polega na kontroli tworzenia schematu bazy danych z perspektywu kodu (code-first). Zdanie to próbowałem napisać w sposób zgodny dla dwóch podejść – jeżeli pojawiły się jakieś wątpliwości mam nadzieje, że zostały rozwiane przez powyższe wyjaśnienie.

Mam nadzieję, że ten wpis stanowi proste i zrozumiałe wprowadzenie do Entity Framework - bez podziału na wersje. W kolejnym wpisie skupimy się już na EF Core zagłębiając się coraz dalej w jego tajniki.

Osoby zainteresowane mogą również zwrócić uwagę na poprzednie artykuły związane z tematyką warstwy dostępu do danych: