Предоставить хранилище как IQueryable
Я хотел бы представить репозиторий как тип IQueryable.
Репозиторий использует Linq для NHibernate для связи с базой данных.
Может кто-нибудь указать мне пример реализации?
Например, как должна выглядеть соответствующая реализация GetEnumerator() в моем репозитории?
Редактировать:
Будет ли что-то подобное уместным?
public class MyTypeRepository : IEnumerable<MyType>
{
IEnumerator<MyType> IEnumerable<MyType>.GetEnumerator()
{
return Session.Linq<MyType>().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<MyType>)this).GetEnumerator();
}
}
4 ответа
Это плохой дизайн.
IQueryable
это вопрос (поиск "запрос" в словаре). Это то, как вы запрашиваете данные. Это то, что вы должны давать в хранилище.
Репозиторий должен возвращать ответы - сами данные.
Если репозиторий возвращает IQueryable, вы в значительной степени отрицаете необходимость в репозитории.
Я думаю, что Репозиторий может дать вам 1 или более IQueryables / IEnumerables, но нет: Репозиторий является IQueryable.
Это может выглядеть так:
public interface IPersonRepository
{
IEnumerable<Person> GetAllPersons();
void AddPerson(Person person);
// more...
}
Вы могли бы вернуться IQeryable<Person>
от GetAllPerson(), но это не может быть улучшением. IEnumerable проще, меньше связывает.
Множество мнений по этому поводу, но Айенде (Орен Эйни), кажется, считает, что IQueryable вполне подходит для возвращения и довольно хорошо формулирует свою точку зрения.
Здесь я вижу два возможных решения:
Откройте IEnumerable и используйте.AsQueryable() при необходимости
// 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); }
Принять выражение в методе репозитория
// 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(); }
Примечание. Ни один фильтр выражений не может быть преобразован в SQL-запрос с помощью Entity Framework.