Entity Framework - Trwałość

Entity Framework umożliwia teraz korzystanie z Entity Framework bez wymuszania, aby każda część aplikacji była świadoma Entity Framework, oddzielając jednostki od infrastruktury. Możesz tworzyć klasy, które mogą skupiać się na swoich regułach biznesowych bez względu na to, jak są one utrwalane (gdzie są przechowywane dane i jak dane są przesyłane między obiektami).

Tworzenie trwałych ignorantów

W poprzednim akapicie opisano metodę, która nie ma dokładnej wiedzy o źródle wykorzystywanych przez nią danych. To podkreśla istotę trwałej ignorancji, która ma miejsce, gdy twoje klasy i wiele naszych warstw aplikacji wokół nich nie przejmuje się tym, jak dane są przechowywane.

  • W wersji .NET 3.5 Entity Framework, jeśli chcesz użyć wcześniej istniejących klas, musisz je zmodyfikować, wymuszając na nich pochodzenie z EntityObject.

  • W .NET 4 nie jest to już konieczne. Nie musisz modyfikować jednostek, aby mogły uczestniczyć w operacjach Entity Framework.

  • To pozwala nam budować aplikacje, które obejmują luźne powiązania i oddzielenie problemów.

  • Dzięki tym wzorcom kodowania Twoje klasy zajmują się tylko własnymi zadaniami, a wiele warstw aplikacji, w tym interfejs użytkownika, nie ma zależności od logiki zewnętrznej, takiej jak interfejsy API Entity Framework, ale te zewnętrzne interfejsy API mogą współdziałać z naszymi podmioty.

Istnieją 2 sposoby (połączone i odłączone) podczas utrwalania jednostki z Entity Framework. Obie drogi mają swoje znaczenie. W przypadku scenariusza połączonego zmiany są śledzone przez kontekst, ale w przypadku scenariusza odłączonego musimy informować kontekst o stanie jednostki.

Połączone scenariusze

Scenariusz połączony ma miejsce, gdy jednostka jest pobierana z bazy danych i modyfikowana w tym samym kontekście. Dla scenariusza połączonego załóżmy, że mamy usługę Windows i wykonujemy pewne operacje biznesowe z tą jednostką, więc otworzymy kontekst, przejdziemy przez wszystkie jednostki, wykonamy nasze operacje biznesowe, a następnie zapiszemy zmiany w tym samym kontekście otwarty na początku.

Przyjrzyjmy się poniższemu przykładowi, w którym uczniowie są pobierani z bazy danych i aktualizują imiona uczniów, a następnie zapisują zmiany w bazie danych.

class Program {

   static void Main(string[] args) {

      using (var context = new MyContext()) {

         var studentList = context.Students.ToList();

         foreach (var stdnt in studentList) {
            stdnt.FirstMidName = "Edited " + stdnt.FirstMidName;
         }

         context.SaveChanges();

         //// Display all Students from the database

         var students = (from s in context.Students
            orderby s.FirstMidName select s).ToList<Student>();

         Console.WriteLine("Retrieve all Students from the database:");

         foreach (var stdnt in students) {
            string name = stdnt.FirstMidName + " " + stdnt.LastName;
            Console.WriteLine("ID: {0}, Name: {1}", stdnt.ID, name);
         }

         Console.ReadKey();
      }
   }
}

Kiedy powyższy kod zostanie skompilowany i wykonany, otrzymasz następujące dane wyjściowe i zobaczysz, że edytowane słowo jest dołączone przed imieniem, jak pokazano w następującym wyniku.

Retrieve all Students from the database: 
ID: 1, Name: Edited Edited Alain Bomer 
ID: 2, Name: Edited Edited Mark Upston

Scenariusze rozłączone

Scenariusz rozłączenia ma miejsce, gdy jednostka jest pobierana z bazy danych i modyfikowana w innym kontekście. Załóżmy, że chcemy wyświetlić niektóre dane w warstwie prezentacji i używamy jakiejś aplikacji n-warstwowej, więc lepiej byłoby otworzyć kontekst, pobrać dane i ostatecznie zamknąć kontekst. Ponieważ tutaj pobraliśmy dane i zamknęliśmy kontekst, pobrane przez nas jednostki nie są już śledzone i jest to scenariusz rozłączenia.

Przyjrzyjmy się poniższemu kodowi, w którym nowa odłączona jednostka Student jest dodawana do kontekstu przy użyciu metody Add.

class Program {

   static void Main(string[] args) {

      var student = new Student {
         ID = 1001, 
         FirstMidName = "Wasim", 
         LastName = "Akram", 
         EnrollmentDate = DateTime.Parse( DateTime.Today.ToString())
      };

      using (var context = new MyContext()) {

         context.Students.Add(student);
         context.SaveChanges();

         //// Display all Students from the database

         var students = (from s in context.Students 
            orderby s.FirstMidName select s).ToList<Student>();

         Console.WriteLine("Retrieve all Students from the database:");

         foreach (var stdnt in students) {
            string name = stdnt.FirstMidName + " " + stdnt.LastName;
            Console.WriteLine("ID: {0}, Name: {1}", stdnt.ID, name);
         }

         Console.ReadKey();
      }
   }
}

Gdy powyższy kod zostanie skompilowany i wykonany, otrzymasz następujące dane wyjściowe.

Retrieve all Students from the database:
ID: 1, Name: Edited Edited Edited Alain Bomer
ID: 2, Name: Edited Edited Edited Mark Upston
ID: 3, Name: Wasim Akram