Repository base classes with LINQ to SQL and performance.

July 18, 2008 19:14 by Rob

I read an article on CodeProject about implementing the repository pattern with Linq To SQL.

I tried that approach because it sounded very nice. I did have some problems with performance and after a few debugging sessions (showing the SQL trace or the DataContext log) I found the problem.


By defining the virtual methods of the repository base class like this: public IEnumerable<T> FindAll(Func<T, bool> exp) the Func will not be (what I call) a delayed method, but it will be expanded immediately. I checked the log from the DataContext and it shows that the table is no longer queries using a where clause. Instead, a full table load is performed and the function is evaluated in memory.


However, the solution is very easy, although this mean you'll have to include the Linq assemblies to your testing bed:

protected T Single(System.Linq.Expressions.Expression<Func<T, bool>> exp)
{
    return Items.Single(exp);
}


The trick is to wrap your functions in a System.Linq expression. Client usage is exactly the same. The performance gain on my project was huge, If you consider that tables are no longer loaded completely into memory.

The full code for my repository base class is in the link below.

Repository.cs (4,64 kb)


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments

Nyla

August 2, 2008 20:34

I don't really understand this. How does this affect the way to work? I noticed that the bll retrieves all information while I only ask for a single instance of for example a product (from Northwind) database.

Nyla

Rob

August 2, 2008 22:52

If you make direct use of the DataContext yourself, there is no problem. However, by using the generic repository baseclass as laid out on codeproject does not make use of 'deferred execution'. The effect is that the SQL statement is generated too soon. This in turn causes the framework to load *all* records in the table and filter the one record in memory, rather than loading the single record you were looking for.

Rob