If you want to have POCO entities and to keep at the same time, the context features like tracking, attaching automatically relationships, Lazy loadings, EF will generate a proxy which inherits your entity classes and which adds some code to do it. This is the same idea than in N-Hibernate. However, in my opinion, it is a bad idea. Indeed, it is very restrictive approach because you can’t have your entities sealed and need to have them public, you must have gets and sets protected or public and virtual, idem for constructor: you have to have a public or protected parameterless constructor. For these reasons, I really don’t like this approach.
I think I am not the only guy who doesn’t like it. However, what else can we do?
My idea was to use Cecil to update my entities instead of inheriting them.
How does it work?
I define a program with two arguments in the Main method: the “normal” entity assembly path and the edmx path. In this program, I inject IL in the existing entities so that they implement INotifyPropertyChanging, INotifyPropertyChanged, IEntityWithChangeTracker, IEntityWithKey and IEntityWithRelationships.
Then in my application, I use the following post-build event:
“D:\Documents\Visual Studio 2010\Projects\EF POCO with Cecil\EFPOCOWithCecil\bin\Release\EFPOCOWithCecil.exe” “$(TargetDir)Entities.dll” “$(ProjectDir)..\DAL\Northwind.edmx”
With these implementations, I can enjoy context features.
I have only one restriction: I have to set navigation properties collection as ICollection<T> (it’s the same with EF to use POCO proxy).
The good point is the fact that we don’t have other restrictions of default POCO implementation. Moreover with EF, if you use CreateObject on your context, you will have an instance of the proxy and if you use directly a new on your entity type, you won’t have the proxy (so without context features). This point is very confusing. With my approach, this problem is solve too.
You can download my code here.