I\'d like to expose a Repository as an \'IQueryable\' type.
The repository uses Linq to NHibernate to communicate with the database.
Can anyone point me at an ex
I think a Repository can give you 1 or more IQueryables/IEnumerables, but not : a Repository is an IQueryable.
It could look like:
public interface IPersonRepository
{
IEnumerable<Person> GetAllPersons();
void AddPerson(Person person);
// more...
}
You could return IQeryable<Person>
from GetAllPerson() but that may not be an improvement. IEnumerable is simpler, less coupling.
Lots of opinions of this one, but Ayende (Oren Eini) seems to think IQueryable is ok to return and articulates his point rather well.
Just return session.Linq<T>()
This is a bad design.
An IQueryable
is a question (lookup "query" in a dictionary). It's how you ask for data. It's what you should be giving to the Repository.
A Repository should be returning answers -- the data itself.
If the Repository is returning a IQueryable, you've pretty much negated the need for the Repository.
I can see two possible solutions here:
Expose IEnumerable and use .AsQueryable() when needed
// Repository
public IEnumerable<Person> GetAll() {
return _dbContext.People.AsQueryable();
}
// Usage
public Person GetByPhone(string phoneNumber) {
var queryablePeople = _personRepository.GetAll().AsQueryable();
return queryablePeople.FirstOrDefault(perspn => person.Phone == phoneNumber);
}
Accept expression in Repository method
// Repository
public IEnumerable<Person> GetPeople(Expression<Func<Person, bool>> filter) {
return _dbContext.People.Where(filter);
}
// Usage
public Person GetByPhone(string phoneNumber) {
return _personRepository.GetPeople(person => person.Phone == phoneNumber).FirstOrDefault();
}
Note: Not any expression filter can be translated to SQL Query by Entity Framework