In a previous article we discussed about POCO-class and entity framework
In this article, we will explore the differences between POCO-class and Entity-Framework generated classes (EntityObject classes). Given below are two code blocks. Compare the code block 1 and 2. You will observe that in the code block 2, the class Customer is inherited from EntityObject class and there are special constructs related to persistence and many attributes related to Entity Framework. Whereas the class in the code block1 does not inherit from any class. It just contains properties.
Given below is a list of differences between them.
- Inherits from EntityObject class
- Created automatically when Entity Data Model is created
- Not persistent ignorant but is persistent aware
- When used in Enterprise Applications, performance hit observed
- Not possible to do Unit Tests
- True Domain Mode implementation is not possible
- Does not facilitate the SOC
- The EF generated classes automatically tracks the changes in entities only if entities are tracked by the ObjectContext, automatic two-way relationship fix-ups and Lazy loading
- Does not inherit from any class
- Created manually or using templates
- Persistent Ignorant
- Extensively used in Enterprise Applications as it facilities layered application development
- Unit tests are possible
- True Domain Mode implementation possible
- POCOs facilitate SOC
- Tracking changes in entities, two-way relationship fix-ups and lazy loading will not happen automatically in POCOs
We have mentioned the word SOC in the table, we will see - What is SOC ?
SOC stands for Separation Of Concerns. It is the process by which we break an application into layers with minimal functionality overlap. A benefit of this modularizing of application, is that the application code is divided into logical layers. SOC pattern has to be implemented, to build an application based on multi-layered architecture.
Above is the screen shot of the SOMEntities.edmx.cs file. The entity framework generated code contains entity classes, all of which are derived from the EntityObject class and also a class inherited from ObjectContext.
Observe that the code block1 is the POCO class which is very simple and straight forward and it contains only properties. Code block2 is the EF generated code and contains factory methods to add, update and delete entities. For example, the CreateCustomer factory method (generated automatically) is used to insert a new customer entity to the database. The code you are seeing is only a part of the code generated by EF. These EntityObject classes are very much bound to the EntityFramework and performing unit tests on these classes is difficult. Because of this reason, if we use these classes in applications, it will not be possible to replace the Data Access Layer with some other data access technology in future. The code also creates a new ObjectSet<TEntity> instance for every specified type. In the code given above, Customers is ObjectSet instance and is used to do operations like querying, adding, modifying, and deleting customer objects. The CreateObjectSet<T> method returns a collection which contains specific objects.
When using these classes, we turn off the code generation option and the EntityObject and ObjectContext classes will not be generated. These classes will not know about ObjectContext and so we need to explicitly create one as shown below.
The article How to Create a POCO class in entity framework, integrate with ObjectContext and write query
Point no. 3 explanation
Consider the point no. 3 in the comparison table, the EF generated classes are not persistent ignorant but are persistent aware. We will discuss this point in detail with saving functionality which is a frequently used operation in database applications. The below code implements the add (save) functionality and demonstrates persistent dependence in generated classes. The AddObject() method adds an entity to the context in the Added state.The context saves the object as a new row in the Customer table using INSERT command. Both the methods AddObject() and SaveChanges() methods are entity framework methods.
As mentioned in the comparison table given above, these classes are Persistent Ignorant. Given below is an example of persistence ignorance. The example implements the add functionality. The Customer class resides in the business layer and the AddCustomer method is not aware of persistent logic.
Point no. 8 explanation:
Change Tracking with EntityObject classes
The EF generated classes inherited from EntityObject class is able to interact with ObjectContext. As you know, the ObjectContext holds a reference and maintains the state of all entity objects. Whenever any change happens to an entity, the entity itself notifies the changes to the ObjectContext, so that ObjectContext is always able to track changes. But these changes are tracked only if entities are attached to the context.
Change Tracking in POCO entities
Tracking the changes in these entities will not happen automatically because these entities will not be able to notify its changes to the ObjectContext. So, ObjectContext needs to synchronize its data. The DetectChanges method of Objectcontext will take care of this synchronization process before persisting data into the database. Change tracking can be done in two ways, Snapshot change tracking without using proxies
and using proxies.
Lazy loading with EntityObject classes
Lazy loading with EntityObject classes is possible through navigation properties. The navigation properties returns EntityCollections and these are the classes which provide lazy loading capability. The article Loading Related Objects in Entity Framework
Lazy loading with POCO classes
loading(Lazy) with these classes is not possible with navigation properties because in these classes the navigation properties will not return EntityCollections and no automatic lazy loading capabilities are possible. If you observe the codeblock1, we have used ICollection (interface) to return the collection and property as virtual while declaring the navigation property. This enables Lazy loading.