Linq to SQL Repository ~theory~ - Generic but now uses Linq to Objects?
- by Matt Tolliday
The project I am currently working on used Linq to SQL as an ORM data access technology. Its an MVC3 Web app. The problem I faced was primarily due to the inability to mock (for testing) the DataContext which gets autogenerated by the DBML designer.
So to solve this issue (after much reading) I refactored the repository system which was in place - single repository with seperate and duplicated access methods for each table which ended up with something like 300 methods only 10 of which were unique - into a single repository with generic methods taking the table and returning more generic types to the upper reaches of the application.
My question revolves more around the design I've used to get thus far and the differences I'm noticing in the structure of the app.
1) Having refactored the code from the dark ages which used classic Linq to SQL queries:
public Billing GetBilling(int id)
{
var result = (
from bil in _bicDc.Billings
where bil.BillingId == id
select bil).SingleOrDefault();
return (result);
}
it now looks like:
public T GetRecordWhere<T>(Expression<Func<T, bool>> predicate) where T : class
{
T result;
try
{
result = _dataContext.GetTable<T>().Where(predicate).SingleOrDefault();
}
catch (Exception ex)
{
throw ex;
}
return result;
}
and is used by the controller with a query along the lines of:
_repository.GetRecordWhere<Billing>(x => x.BillingId == 1);
which is fine, and precisely what I wanted to achieve.
...however.... I'm also having to do the following to get precisely the result set i require in the controller class (the highest point of the app in essence)...
viewModel.RecentRequests = _model.GetAllRecordsWhere<Billing>(x => x.BillingId == 1)
.Where(x => x.BillingId == Convert.ToInt32(BillingType.Submitted))
.OrderByDescending(x => x.DateCreated).
Take(5).ToList();
This - as far as my understanding is correct - is now using Linq to Objects rather than the Linq to SQL queries I was previously? Is this okay practise? It feels wrong to me but I dont know why. Probably because the logic of the queries is in the very highest tier of the app, rather than the lowest, but... I defer to you good people for advice. One of the issues I considered was bringing the entire table into memory but I understand that using the Iqeryable return type the where clause is taken to the database and evaluated there. Thus returning only the resultset i require... i may be wrong.
And if you've made it this far, well done. Thank you, and if you have any advice it is very much appreciated!!