A couple of years ago when the overall shape of what we would ship in the first release of the entity framework became apparent, I realized that one of the biggest issues users of that release would fight with was creating N-tier applications. So I started a project to explore the space by creating something I called EntityBag. In spite of the fact that I wasn’t too thrilled with the overall approach, I thought it would be a good exercise and if nothing else it would help illuminate the issues with building this kind of application on the EF and demonstrate to folks what techniques they could use with the EF to solve these problems. The result of this investigation was a series of blog posts and a sample project which I uploaded to code gallery. You can check out the project at: http://code.msdn.microsoft.com/entitybag/ That site also has links to each of the relevant blog posts which is where the real interesting data lives.
At the time that I created EntityBag (mostly January 2008), the version of the Entity Framework was called “beta 3”, and it was before the first RTM of the product. Unfortunately, when the first version was finally released we included a change to by default generate classes which would serialize an entire graph of related entities as one (at beta 3 only one entity would serialize at a time) which ended up breaking EntityBag and the fix involved fairly major surgery. From the beginning this project had never been intended as a full-quality production solution—I just wanted to teach people how they could use the EF to build the right solutions for their particular projects. In addition I wanted to work with the team to produce a much better, long-term solution for N-tier apps, so whatever time I had available for this topic I poured into the next release of the EF (EF4) rather than into updating the EntityBag project.
The team has been working hard to make N-Tier much easier with EF4, and the result is several key features that are available now when you combine Beta 2 of VS2010/.NET 4 and yesterday’s release of what we call the EF Feature CTP 2.
The first critical addition to the product are core changes to the ObjectContext and ObjectStateManager APIs which make working with entities which spend some time detached from a context MUCH easier. These changes were described about a year ago in this post to the EF Design blog. There have been a few small adjustments to the APIs as we went through the experience of the first and second betas for this release, but the core changes are all there along with much of the reasoning behind them.
Next, we added support for foreign-key relationships which allow FK properties to be added to entities, and the system does intelligent fixup between the FK properties and the collection and reference “navigation” properties which were the only representation of a relationship which the EF had in its first release. FK relationships are important to N-Tier apps for two reasons: First off, they make it easier to support scenarios where you don’t want the perf hit (magnified in N-tier applications) of retrieving an entire object in order to establish a relationship. With FK properties you can just set the key value for the relationship. This was possible before by setting an EntityKey property, but that was harder than it should have been and MUCH harder (and sometimes impossible) when you have POCO entities. Even more interesting for N-tier applications, though, is the fact that FK relationships give the EF the knowledge that a relationship’s persistence is fundamentally tied to a particular entity rather than being conceptually completely separate, and this is important because it allows the EF to use concurrency checks for the entity to cover concurrency checks for the relationship as well. In the first release of the EF, the framework had no way to know from the conceptual model which if any entity “contained” the FK for the relationship so it performed concurrency checks for the relationships separately from the entities which meant that you needed the original value of a relationship not just the original value of whatever concurrency token you used for the entity. Uggg… That’s a little long-winded and obtuse, but the key point to realize is that having FK-relationships makes n-tier applications more efficient and intuitive in at least a couple of ways.
Finally, we had resounding feedback in response to the initial N-tier post on the EF Design blog and in other places saying that while the core APIs were flexible and made things easier, there was still just too much work required to build end-to-end N-tier solutions. So we created the self-tracking entities template which ships for now in Feature CTP 2 but will be in the box when .NET 4 launches on March 22, 2010. Self-tracking entities won’t be right for everyone, and for those folks where they aren’t a great fit as is there will either be the option to modify the template (Long live T4!) or to write code by hand using the core API improvements on which the STE template is built. If they do match your situation, though, they make things MUCH easier. The amount of code required is dramatically less, and the functionality is really pretty great. You can write simple service methods that return entities. On your client (which does NOT require .Net 4 or any version of the entity framework—it works on silverlight, for instance) you can manipulate entity graphs by adding, deleting and modifying entities as well as splicing more than one graph together if you like, and the entities will keep track of the minimum required set of original values as well as whatever changes are made to them all by themselves. NO BAGS OR OTHER EQUIPMENT REQUIRED. The only constraint is that you must use the generated self-tracking entity code on your client (not a simple proxy). Then back on your service, the code to reattach that graph to the context with appropriate original values and all the tracking information is literally one method call: ApplyChanges.
In addition to the posts referenced above, I recommend taking a look at the Self Tracking Entities walkthrough which was published after the first release of the feature CTP. The current release of the STE template is a little different, but this is a great starting point, and more information will be available on the ado.net team blog soon. The other resource to consider is that over the course of this summer I wrote a short series of articles in MSDN magazine about the topic of N-Tier in general and especially around using it with the Entity Framework. The third article in that series just came out in the November issue, and it contains samples both of using STEs and using the core APIs to build other N-tier solutions. You can find the articles online here:
So, death to EntityBag! Long live EF4!