My Foray into Linq to Sql and the Entity Framework (Part 1 of 2)
Recently I had a project in which I knew that I wanted to use one of the new O/RM tools from Microsoft. If you don’t know what an O/RM tool does, then let me give my brief explanation. An O/RM tool creates mappings from the database to an object models. This really cuts down on manual mappings and manual creation of objects and is a great option for Rapid Application Development.
Why are there two tools?
So, the most obvious question is – why are there two tools for O/RM in the Microsoft stack? Well, I am not really sure, but I know the timeline a little – so you can draw your own conclusions.
Linq to Sql came out first and Linq to Sql was never even supposed to exist. Well, at least that is what Matt Warren’s blog says: http://blogs.msdn.com/mattwar/archive/2007/05/31/the-origin-of-linq-to-sql.aspx. So, what happens at your company when a developer builds something and it gets released even though it wasn’t spear headed by the company – politics begin? I am not saying that happened here, but soon after Linq to Sql comes out we have a new O/RM tool from Microsoft, the Entity Framework. This new tool does almost everything Linq to Sql does, and it does it in similar ways. But, it was created separately and it scales a little more. Even though some people think that some of the smaller nuisances in Linq to Sql are actually better than the Entity Framework, but that debate is not one I will get into during this blog.
This new O/RM tool, the Entity Framework, has the ability to hook into more database types. It also has some more advanced mapping configurations. It decouples the database structure from the logical data model better than Linq to Sql. And, it is easier to use with stored procedures. However, it is not as “lightweight” as Linq to Sql and is suppose to work with all databases, thus it doesn’t take advantage of some of the unique features of particular databases. But, hopefully some better adapters will come out soon for particular databases that will increase performance.
I heard Microsoft was killing off Linq to Sql?
Well, I am not 100% sure yet on this statement. From what I hear Microsoft will continue to “support” Linq to Sql, however we might not see any extra features added to it. I have seen statements that Microsoft will continue to invest in Linq to Sql based on customer feedback, but the Entity Framework is the recommended data access solution for .net 4.0. What this tells me is that when .net 4.0 comes out we will see enhancements to the Entity Framework and we will continue to see enhancements to the Entity Framework from there on out. But, at the same time the word “dead” might not be appropriate for Linq to Sql. While we might not see many improvements, Microsoft should continue to support this technology.
Please refer to this article by Jonathan Allen on InfoQ explaining these thoughts a little more: http://www.infoq.com/news/2008/11/DLINQ-Future
Also, here is the Microsoft blog that clarifies the future of Linq To Sql: http://blogs.msdn.com/adonet/archive/2008/10/31/clarifying-the-message-on-l2s-futures.aspx
Choosing one or the other
Well, based on my previous statements you would think it is obvious to choose the Entity Framework. However, on my last project I actually still chose Linq to Sql. Why would I do that? It has to do with established patterns and tools, let me explain. I was building an asp.net application and I wanted to use a repository pattern.
The repository pattern allows me to set up Retrieve, Update, Insert, etc… statements in a repository class. This class takes care of using my object to attach to the data context in Linq to Sql and then runs the respective Linq to Sql data access operation. It is a great pattern and one I recommend for asp.net projects and multi-tiered projects in Linq to Sql.
Well, one big feature of the repository pattern is re-attaching disconnected objects. On this particular project we had a real short deadline and needed every advantage we could get. Plus, this project had a very well defined database that mapped perfectly to the object model. It was really setup for a lightweight O/RM tool. Luckily, I found a project on CodePlex specifically designed to re-attach disconnected objects in Linq to Sql – http://www.codeplex.com/LINQ2SQLEB. This project is basically a base class for Linq to Sql that has the ability to re-attach disconnected objects. I couldn’t find anything similar for the Entity Framework at this point (probably because it is newer). So, that is why I decided to go with Linq to Sql.
What do you mean when you keep mentioning Disconnected Objects?
Ok, I have mentioned Disconnected Objects a bunch in the last section. So, if you don’t understand what I mean by that, let me explain the architecture of both Linq to Sql and the Entity Framework a little. Both of these tools use a graphical interface that creates your objects. However, they actually create two things:
So, the first thing to understand is what is a context versus an object? The easiest one to understand is the objects. These are the actual objects that represent the tables in your database. These are dynamically built by the frameworks, but they are basically classes with properties (just like we would do if we did the mapping manually ourselves). So, there is nothing too fancy about the actual objects that get created.
The fancy stuff in these frameworks is the Context. The Context is what you use to populate the objects. For example, you want to run a retrieve, you tell the Context to retrieve the data and it populates the objects. Or, you want to save, you tell the Context to save, and it saves the objects that were previously retrieved. The Context also remembers “state”. State is important because it remembers if the object is New, Modified, Deleted, etc… This becomes really important during save operations. The framework needs to know the state to know what kind of sql statement to run (Update, Insert, Delete). The Context also keeps the original values from the initial load and can use these initial values to do optimistic concurrency checks when saving. This architecture is great for WinForM or Silverlight applications, but can produce issues with Postback scenarios in asp.net (we will explain this later in the article).
So, hopefully I adequately explained what the Context does and what the Objects are for. But, I still haven’t explained Disconnected Objects. Disconnected Objects can happen in many ways, but I will explain in terms of asp.net. Let’s say you use the Context, to call the framework, to populate your objects. And, let’s say you are doing this in the OnLoad of your asp.net page. Now let’s say the normal asp.net processing takes place and when you finish the user hits the Save button. The Save button does a PostBack at this point. Well, there is your issue. As soon as you do the PostBack you have lost the reference to your Context and your objects.
Ok, I have lost my references, how do I get them back. Well, you could just instantiate new objects and fill them in. However, that is all you will have, new objects. This is now a Disconnected Object scenario. Your objects have been disconnected from your Context.
In the next part of this series we will discuss the different options for reattaching those disconnected objects.