Предоставить хранилище как 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 вполне подходит для возвращения и довольно хорошо формулирует свою точку зрения.

Здесь я вижу два возможных решения:

  1. Откройте 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);
    }
    
  2. Принять выражение в методе репозитория

    // 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.

Просто вернись session.Linq<T>()

Другие вопросы по тегам