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:

1.       Context

2.       Objects

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.

Site Information Viewer

Recently in the SharePoint Development Forum on msdn, there was a thread going around about viewing certain things from the SharePoint API. These threads dealt with viewing the users associated to sub-sites and viewing the template the sub-site was created with. Of course, myself and others replied with code snippets of how to do it. During the discussion someone asked me if I could post the webpart I had (in which I got the code snippet from) to CodePlex. I was about to put it on CodePlex “as is” and I realized it was really too simple to put it on CodePlex “as is”. So, I decided to build a simple administrative WebPart called the “Site Information Viewer”. This WebPart enumerates the sub-sites of the site collection it is on and shows a tree view. You can click on any site in the tree view and it will show you valuable information from the SharePoint API about the particular site.

A more detailed description of the webpart can be found here: http://www.codeplex.com/RDACollaboration/Wiki/View.aspx?title=Site%20Information%20Viewer%20WebPart

The release for the webpart is with the other RDA CodePlex releases found here: http://www.codeplex.com/RDACollaboration/Release/ProjectReleases.aspx?ReleaseId=15218

2

I can’t retract my solution!

Ok, I have seen this issue a bunch and the first time I ran across it I didn’t know what to do. I should have written a blog about it then, but forgot. Then, the other day a colleague of mine ran across the same issue. So, I decided to write a blog and hopefully help someone else in the future.

Have you ever tried to retract a solution in Central Administration and it then sits on “Retracting”. Then, after it is done it still says “Deployed”. And, to make matters worse, you don’t see an error message. Why does this happen?

Well, I know of one way that is very common. If you originally deployed to all webs, instead of specifying the web applications to deploy to, then you can get this issue. In fact, if you use a tool like WSPBuilder, and you use their deploy command in Visual Studio, you are deploying to all web applications.

Here is the issue, after you do a retract and use “allcontenturls”, which is the default if you just say retract all web applications in Central Administration, then it has an issue. The issue is that it won’t retract the solution from Central Administration itself. In order to retract the solution from Central Administration, you have to choose it specifically to retract. You can do this through stsadm and point directly to the central administration url. Or, you can go into Central Administration and when you go to the retraction screen you can pick the Central Administration web application from the dropdown list.

Usually I just do my retractions in Central Administration. So, when I originally do a “deploy to all web applications”, I then have a 2 step process to retract. Step 1: Retract from all Web Applications. Step 2: Retract specifically from Central Administration.

Hopefully this helps someone in this situation. I am sure there are more reasons why a web application won’t retract, but this is a common scenario I have seen.