Thursday, January 29, 2009

LINQ to SQL vs. LINQ to Entity Framework

No, this isn't a cage match. Sorry to those who expected otherwise.

What I do want to point out is that the programming models are different, and differ in ways that are going to make some people think that certain features are missing from one tool or the other. If you're one of those people who thinks that LINQ to SQL has a performance problem because of lazy loading, or that LINQ to Entity Framework doesn't give you a way to turn off change tracking for query-only usage, then I'm talking to you, friend!

For instance, let's look at that change tracking issue. Both LINQ to SQL and LINQ to EF will track changes to entities so that you can change data in an object and save the data simply by submitting changes through the DataContext or ObjectContext. But for query-only operations, this change tracking is unnecessary, and you can turn it off. Here's how you do it in LINQ to SQL:

public static List<Customer> GetCustomers()
{
using (NorthwindData dc = new NorthwindData())
{
dc.ObjectTrackingEnabled = false;
return (from c in dc.Customers select c).ToList();
}
}

And here's how you do it in LINQ to Entity Framework:

public static List<Customers> GetCustomers()
{
using (NorthwindEntities ne = new NorthwindEntities())
{
ne.Customers.MergeOption = MergeOption.NoTracking;
return (from c in ne.Customers select c).ToList();
}
}

Note the big difference here. In LINQ to SQL, you turn off tracking in the DataContext. In LINQ to EF, you turn off tracking in the entity collection. If you're looking in the wrong place, you'll miss it.

The same pattern holds true with eager loading and lazy loading. In LINQ to SQL, it's controlled with a DataLoadOptions object attached to the DataContext. In LINQ to EF, it's set at the entity level, either in the query (eager loading) or in processing the results (lazy loading).

I'll cover eager loading and lazy loading in a follow-up post, because there's a nasty surprise waiting in LINQ to SQL eager loading.