A Simple Generic Repository for Linq to SQL

Two code posts in one day, aren’t you lot lucky?

I’m currently working on a small project working with Microsoft ASP.NET MVC. I admit I’m rather enjoying the experience, it’s nice to get back to proper bare metal GETs and POSTs with non of the fluff of normal ASP.NET getting in the way. Since this is a relatively simple project I’m using Linq to SQL rather than the Entity framework. Whilst putting some boilerplate code together (after following the excellent NerdDinner tutorial) I realised there was a lack of a simple generic repository for common object operations. So I present to you my basic, generic repository:

class="brush: csharp; title: ; notranslate" title="">using System.Data.Linq.Mapping; using System.Linq; using System.Linq.Expressions; using BrandingScience.Models; using System;</p>

public abstract class Repository<T, C> where T : class where C : System.Data.Linq.DataContext, new() { private C db = new C();

>// Query Methods public IQueryable FindAll() { return db.GetTable(); } public T Get(int id) { MetaTable mapping = db.Mapping.GetTable(typeof(T)); MetaDataMember pkfield = mapping.RowType.DataMembers.SingleOrDefault(d => d.IsPrimaryKey); ParameterExpression param = Expression.Parameter(typeof(T), "e"); var p = Expression.Lambda<Func<T, bool>>( Expression.Equal(Expression.Property(param, pkfield.Name), Expression.Constant(id)), new ParameterExpression[] { param }); return db.GetTable().SingleOrDefault(p); } // Insert/Delete public void Add(T t) { db.GetTable().InsertOnSubmit(t); } public void Delete(T t) { db.GetTable().DeleteOnSubmit(t); } // Persistence public void Save() { db.SubmitChanges(); } </code></pre>

} </pre> T is the table class you want to create the repository for, C is the DataContext created by Linq to SQL. Pretty straightforward. A typical implementation looks like this:class="brush: csharp; title: ; notranslate" title="">public class JobRepository : Repository<Job, MyDataContext> { }</p>

public static void Main(string[] args) { JobRepository jobRepository = new JobRepository(); List allJobs = jobRepository.FindAll();</p>

// Return a single item and change the title.
Job job = jobRepository.Get(1);
job.Title = "Mutated Gerkhin Production";

// Create a new item.
Job newJob = new Job();
newJob.Title = "Mutated Gerkhin Anti-Coagulant Production";
jobRepository.Add(newJob);

// Delete an old item.
Job removeJob = jobRepository.Get(2);
Console.WriteLine(removeJob.Title); // Output: Survival of human race.
jobRepository.Delete(removeJob);

// Save all changes to the repository.
jobRepository.Save();