Entity Framework - Persistence



Entity Framework now allows you to benefit from the Entity Framework without forcing every part of your application to be aware of the Entity Framework, separating entities from the infrastructure. You can create classes that can focus on their business rules without regard to how they are persisted (where the data is stored and how the data gets back and forth between your objects).

Creating Persistent Ignorant Entities

The preceding paragraph described a method that has no intimate knowledge of the source of the data it consumes. This highlights the essence of persistence ignorance, which is when your classes and many of our application layers around them don’t care how the data is stored.

  • In the .NET 3.5 version of Entity Framework, if you wanted to use preexisting classes, you were required to modify them by forcing them to derive from EntityObject.

  • In .NET 4 this is no longer necessary. You don’t have to modify your entities in order for them to participate in Entity Framework operations.

  • This allows us to build applications that embrace loose coupling and separation of concerns.

  • With these coding patterns, your classes are only concerned with their own jobs and, many layers of your application, including the UI, have no dependencies on external logic, such as the Entity Framework APIs, yet those external APIs are able to interact with our entities.

There are 2 ways (connected and disconnected) when persisting an entity with the Entity Framework. Both ways have their own importance. In the case of a connected scenario the changes are tracked by the context but in the case of a disconnected scenario we need to inform the context about the state of the entity.

Connected Scenarios

Connected scenario is when an entity is retrieved from the database and modified in the same context. For a connected scenario let us suppose we have a Windows service and we are doing some business operations with that entity so we will open the context, loop through all the entities, do our business operations and then save the changes with the same context that we opened in the beginning.

Let’s take a look at the following example in which students are retrieved from database and update the students’ first name and then save changes to the database.

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();
      }
   }
}

When the above code is compiled and executed you will receive the following output and you will see that Edited word is attached before the first name as shown in the following output.

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

Disconnected Scenarios

Disconnected scenario is when an entity is retrieved from the database and modified in the different context. Let's suppose we want to display some data in a Presentation Layer and we are using some n-tier application, so it would be better to open the context, fetch the data and finally close the context. Since here we have fetched the data and closed the context, the entities that we have fetched are no longer tracked and this is the disconnected scenario.

Let’s take a look at the following code in which new disconnected Student entity is added to a context using the Add method.

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();
      }
   }
}

When the above code is compiled and executed, you will receive the following output.

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
Advertisements