I’m sure you’re all tired of me blogging about L2S, but I still like it. It’s just so simple and easy to use. Obviously with .net 4.0, the big issues with L2S seem to be resolved. Alongside l2sprof, LINQ to SQL can be very effective. Anyhow, I thought I’d share a simple generic repository I made.
public class LinqToSqlRepository<TContext>
: IDisposable where TContext : DataContext, new()
{
private readonly DataContext _dc;
public LinqToSqlRepository()
{
_dc = new TContext();
}
public T Load<T>(object id) where T : class
{
return _dc.GetTable<T>().SingleOrDefault(BuildWhereClause<T>(id));
}
public void Update<T>(T entity) where T : class
{
_dc.SubmitChanges();
}
public void Insert<T>(T entity) where T : class
{
_dc.GetTable<T>().InsertOnSubmit(entity);
_dc.SubmitChanges();
}
public void Insert<T>(IEnumerable<T> entities) where T : class
{
_dc.GetTable<T>().InsertAllOnSubmit(entities);
_dc.SubmitChanges();
}
public IQueryable<T> Query<T>() where T : class
{
return _dc.GetTable<T>();
}
public void Delete<T>(T entity) where T : class
{
_dc.GetTable<T>().DeleteOnSubmit(entity);
_dc.SubmitChanges();
}
public void DeleteAll<T>(IEnumerable<T> entities) where T : class
{
_dc.GetTable<T>().DeleteAllOnSubmit(entities);
_dc.SubmitChanges();
}
public void Dispose()
{
_dc.Dispose();
}
private Expression<Func<T, bool>> BuildWhereClause<T>(object id) where T : class
{
var parameter = Expression.Parameter(typeof(T));
var whereExpression = Expression.Lambda<Func<T, bool>>
(
Expression.Equal(Expression
.Property(parameter
, GetPrimaryKeyName<T>())
, Expression.Constant(id))
, new[] { parameter }
);
return whereExpression;
}
private string GetPrimaryKeyName<T>()
{
var primaryKey = _dc.Mapping
.GetMetaType(typeof(T))
.DataMembers
.SingleOrDefault(m => m.IsPrimaryKey);
if (primaryKey == null)
throw new MissingPrimaryKeyException();
return primaryKey.Name;
}
}
Here's how you'd use the repository.
public class SampleClass
{
public SampleObject GetById(int id)
{
using(var repository = new LinqToSqlRepository<SampleDataContext>())
{
var result = repository.Load<SampleDataModel>(id);
return Mapper.Map<SampleObject>(result);
}
}
}
Basically, you just pass in the DataContext you want to use and then call the method needed.
As usual, please let me know if you see any improvements that can be made or if you have any questions.