This post will introduce the Entity Framework 4.0, its features and its comparison to Entity Framework 3.5
This is my first post on one of the ways of applying the Repository, Specification and Unit of Work pattern using the persistence ignorance POCO with the upcoming ADO.NET Entity Framework 4.0. ADO.NET Entity Framework 4.0 is currently in Beta 1 which was released to the public on 13 May 2009. These technologies are still in their beta phase and subject to change in the final releases. The sample project comes with this post may or may not work after the official release of Visual Studio 2010 and .NET framework 4.0
Before I go on further, I would like to outline the prerequisites that you need to have in order to run the sample project attached with this post.
- .NET Framework 4.0 Beta 1
- Visual Studio 2010 Beta 1 ( I am using the professional edition)
- ADO.NET Entity Framework Feature CTP 1 (Set of features build on top of the Entity Framework 4.0 Beta 1 which includes the following :
- Template for Self Tracking Entities (N-Tier support for distributed application)
- Template for POCO Entities.
- Code-Only Programming Model.
- SQL server 2005/2008 instance with any name you like as long as you change it to match in the App.Config file for the Unit Test project comes with this post.
- NorthWind database.
The ADO.NET Entity Framework Feature CTP 1 is required because I am using the T4 Template for POCO Entities to generate the domain entities, which comes as part of the CTP 1. T4 stands for Text Template Transformation Toolkit. It is a template engine that is already shipped with Visual Studio 2008. The Entity Framework 4.0 leverages T4 to allow customization of code generation.
ADO.NET Entity Framework 3.5 (v1.0)
ADO.NET Entity Framework is the Microsoft’s initiatives to reduce the impedance mismatch that occur across various data representations because of the relational nature of the data stores (MS SQL Server, Oracle and etc) and the object oriented nature of the object stores (Business entities). Developers spend most of the times focusing on complexities of bridging disparate data representations. This is clear that there is a need of having Object Relational Framework/ Tool to reduce these complexities so that the developers can be more productive and focus on the needs of the business application.
We also see the debut of new language feature, LINQ (Language Integrated Query) in C# 3.0 which serves as common language query for all the data stores/sources regardless of their underlying implementations. Developers can use the same keywords similar to the SQL, SELECT, FROM, WHERE and a fleet of operators to query the entities (LINQ to Entities), dataset (LINQ to Dataset), XML (LINQ to XML). More and more data components can be LINQ-enabled to provide high level of abstraction and in the mean time increase developer productivity. This is achievable by implementing the System.Linq.IQueryable interface in the System.Linq namespace and assembly for the component we want to LINQ-enable.
Microsoft introduces the first version of the Entity Framework in its offering of first service pack for the .NET Framework 3.5 .However; the offerings don’t go so well because of the missing of some of the features that will follow suit. From here onward, when I refer to the EntityObject or IPOCO entity, it means the auto generated entities from the Edmgen tool or the Entity Data Model Designer/Entity Designer itself. POCO, the Plain Old CLR Object is the entity that is persistence ignorance. It doesn’t derive from EntityObject class and implementing the IPOCO interfaces (IEntityWithChangeTracker, IEntityWithRelationShips and IEntityWithKey)
- Persistence Ignorance for POCO to achieve separation of concerns between the data and business domain layers. The entities generated from the Entities designer have a tight coupling to the data persistence technology. In this scenario, it is the System.Data.Entity assembly (c:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.Entity.dll) comes with the Entity Framework. For e.g. the scalar property type of an entity type is decorated with System.Data.Objects.DataClasses.EdmScalarPropertyAttribute, the entity type itself is decorated with System.Data.Objects.DataClasses.EdmEntityTypeAttribute. The entity objects need to inherit from the System.Data.Objects.DataClasses.EntityObject to make it as real EF entity. In order to support the change tracking, the entity itself needs to implement System.Data.Object.DataClasses.IEntityWithChangeTracker interface. In order to support the relationship with other entity objects, the entity itself need to implement System.Data.Object.DataClasses.IEntityWithRelationships interface. In the domain driven design approach, this has spoilt the purity of the domain model because of the intrusion of the data access infrastructure concern. The lack of the persistence ignorance feature also causes the business domain logic harder to be read, written and maintained.
- Transparent Lazy Loading support. There is excess code needed to deal with lazy loading. In other words, you have to explicitly make a call to the Load method of the System.Data.Object.DataClasses.RelatedEnd object before you can access to the EntityObject based object’s navigation property. Otherwise, the System.NullReferenceException will be thrown. RelatedEnd is the base class for the System.Data.Object.DataClasses.EntityCollection
which is used to represent the collection objects on the many end of the relationship and System.Data.Object.DataClasses.EntityReference which is used to represent a related end of an association with multiplicity of zero or one for the EntityObject based entities. Every Load method call will actually cause a round trip to the database to fetch the relevant data. To avoid this redundant fetch, the IsLoaded property of the RelatedEnd object need to be checked to decide whether you really need to make a call to the Load property. This is not intuitive and also incurs performance cost if you need to process a collection of EntityObject based object including their navigation properties. For each iteration of the EntityObject based collection, you have to make a call to the IsLoaded property and then decide whether to call the Load method.
- Model First which is a hot design pattern for the enterprise application that requires starting with optimal design of business objects and relationships instead of the schema of the relationship database whose job is to persist data. Data centric approach can lead to suboptimal business object design.
ADO.NET Entity Framework 4.0 (v2.0)
This is the upcoming release of the Entity Framework as part of the .NET Framework 4.0 and Visual Studio 2010. Despite the vote of no confidence and tester complaints, Microsoft doesn’t drop the controversial EF v1. Instead, Microsoft continues to make feature adjustments and has pledged to have transparency in the design process of the Entity Framework v2. Click here to know more about the transparency in design process. The feedback on EF v1 has been around the issues of Domain Driven Design and Development. So, Microsoft has invited some members who have notable credentials in the Domain Design area to be part of the EF advisory council. It will put Microsoft on the right track to deliver tools that are useful for Domain Driven Design and Development. Among the members of the EF advisory council are Eric Evans, Stephen Forte, Martin Fowler, Pavel Hruby, Jimmy Nilsson and some of the folks from Microsoft.
Most of the new features and enhancements in this Beta 1 release are in accordance with the principles of Domain Driven Design and Development. We know that practicing the DDD does not depend on the use of any software tool and framework. However, with these tools and frameworks, technical machinery underneath will be hidden from the developers and development can be made faster because developers can focus primarily on the domain modeling and logic as opposed to the specific technology that implement the system. (Data agnostics)
As of the EF v2 Beta 1, the following features and enhancements have been made public:
- Persistence Ignorance – This would mean your POCO are data agnostics. In EF v1, your POCO have tight coupling with the EntityObject, IPOCO interfaces and other EDM attributes. The decoupled pattern between the POCO and the persistence technology allow the data layer to be completely swap out without affecting the POCO entities should the need arise. This is possible because the POCO entities are placed in its own assembly separated from the assembly that contain the EF’s System.Data.Objects.ObjectContext and which has reference to the System.Data.Entity assembly.
- T4 Code Generation – Create customized code generation template. EF CTP 1 comes with T4 template for POCO class and Self-Tracking Entities where you can modify to fit your needs.
- Transparent Lazy Loading – Defined by the delay initialization of object until the point that they are needed. As I have mentioned previously, the EF v1 support lazy loading through the uses of Load () method and the IsLoaded property of the RelatedEnd based navigation properties for the EntityObject based entities. Now, the loading of the entities is determined by the Entity Framework and this is performed when only it is absolutely necessary. Entity Framework will handle it transparently without the need of having the developers to do any coding. Developer’s responsibility is just only to turn it on or off. The folks at Microsoft call lazy loading as deferred loading. Conceptually, there is no difference. The way it is called because the name of the API that is used to turn it on or off is called “DeferredLoadingEnabled”. However, this property has been changed to LazyLoadingEnabled in EF 4.0 Beta 2.
- POCO Change Tracking – It is required to detect and resolve conflicts that can occur when more than one user updates an instance of a particular record in the relational store. It is particularly important in optimistic and pessimistic concurrency update. EF v1 has already provided the change tracking facilities to the EntityObject/IPOCO based entities. EF v2 provides two types of change tracking. Snapshot based change tracking and notification based change tracking with proxies. Snapshot based change tracking is automatically by the EF provided to your POCO. In this scenario, the EF itself will maintain a snapshot of the before and after property values of your POCO entities which are later used during the System.Data.Objects.ObjectContext.SaveChanges () method is invoked to persist data. These before and after changes values are used by the EF to determine what value has actually changed. However, this kind of comparison is rather expensive compared to the change tracking enjoyed by the EntityObject/IPOCO based entities. In order to have the POCO entities to enjoy the same change tracking performance already with the EntityObject/IPOCO based entities, notification based change tracking with proxies is introduced. To leverage it with the POCO entities, the mapped property of the POCO entity must be virtual and have public access modifier with both the getter and setter. The entity type must be declared as public, non sealed, non abstract, can’t implement the IEntityWithChangeTracker and the IEntityWithRelationShips interfaces. The mapped collection properties that represent the many end of a relationship must be declared as System.Collections.Generic.ICollection
only. During runtime, the EF v2 can provide its own implementation of the proxy for the mapped properties. This proxy instance is based on the type of your own POCO entity. So all the functionalities we have for our own POCO entity is retained. Please refer to the MSDN online documentation for more information.
- N-Tier Support through Self-Tracking Entities – Self-Tracking entities are domain classes that do not have any dependency on the EF but they themselves have the self tracking facilities built in to support self change tracking on their scalar, complex properties, collection and references. This feature is very useful in N-Tier distributed application. For e.g. a web or window client submit a soap request to the WCF services which return an entity object for the client to manipulate. Later, the client and submit back entity object with the modifications to the WCF service for updating. The service itself will perform validation and update to the database store using the Entity Framework.
- Model First Development – Focus on developing the entity model for the business domain first instead of the table schema in the relationship store. After the entity model is finish, then only the SQL scripts for the database schema is generated from the Entity Data Model Designer. The generated SQL scripts can be used to create the persistence store. You will be taking control of the entire process.
- Code Only Development – This is ideal for developers who just want to write domain classes code but don’t bother to touch on the entity designer or any XML associated with the EF.
- Foreign Key Support - Foreign key support is new EF v2. It is called FK association. The association comes with the EF v1 is called first-class or independent association. The FK association is simple to use because it need no mapping and simply mapping the EntitySet in the Entity Model Designer is sufficient. The independent association requires independent mapping among the EntitySets. However, there is argument over that FK association will pollute the conceptual model because the FK belong to the relational world not the object world. FK is used to represent the relationships in the relational database. In object oriented world, the best way to represent object relationships is through object references.
- Better singularization and pluralization of the Entity types naming.
- Complex type support – You can create complex type property in your POCO entity. It is just the same you do for the normal class. Once you have declare the class, you can use them for declaring your complex type based properties in your POCO class.
- Entity Model Designer Improvement where you can have more control over the storage, conceptual and mapping schemas.
At this juncture, I would say that Microsoft has finally listened and learned from their mistakes to produce an ORM framework and tool that they can be proud of and that the developers can easily use to solve the relational and object world impedance mismatch problem while enable us to architecting more complex enterprise applications.
I will continue my discussion on the Repository, Unit of Work and Specification pattern with the source codes I have prepared in my next post as I still in my final stage of finalizing the source codes and project solution.
See you in my next post.
Bye & stay tune...
- ADO.NET Team Blog -> http://blogs.msdn.com/adonet/default.aspx
- Entity Framework Design -> http://blogs.msdn.com/efdesign/