Можно ли скрыть IQueryable от контроллеров, но при этом можно разбивать на страницы и сортировать? - PullRequest
1 голос
/ 08 марта 2011

Фон

Я работаю над веб-приложением с использованием шаблона единицы работы / хранилища. Я выбрал сервисный уровень, который взаимодействует с репозиториями. Репозитории возвращают IQueryable на сервисный уровень, а сервисный уровень возвращает List на контроллеры.

Я решил не возвращать IQueryable в контроллер, чтобы убедиться, что запросы будут повторно использованы и помещены на соответствующий уровень - уровень обслуживания. Кроме того, потому что веб-службы могут потребоваться позже.

Вопрос

Как лучше всего разрешить разбиение на страницы и сортировку на уровне контроллера, не выставляя IQueryable на уровне контроллера?

Один из вариантов - добавить параметры ко всем сервисным функциям, которые могут возвращать несколько объектов, но это не кажется идеальным. В качестве альтернативы я мог бы по-прежнему просматривать страницы в возвращенных списках, но это может привести к большому количеству ненужного доступа к данным.

Изменить для уточнения

Мой репозиторий имеет такую ​​функцию:

public IQueryable<T> GetAll()
{
    return objectSet;
}

Мой сервис имеет такую ​​функцию:

public List<Person> GetAllPeople()
{
    return repository.GetAll().ToList()
}

Я счастлив, что хранилище возвращает IQueryable службе, поскольку это позволяет службе иметь такие функции, как: GetPersonByName, GetPersonByEmail и т. Д.

Но я ищу альтернативу простому назначению функции GetAllPeople над параметрами «PageNumber» и «PageSize».

Ответы [ 4 ]

2 голосов
/ 08 марта 2011

Определенно наиболее эффективный способ реализовать подкачку как можно ближе к базовому хранилищу.Имея это в виду, я полагаю, что стоит принять параметры разбиения на страницы в ваших методах уровня обслуживания.

Мои $ 0,02: это один случай, когда теория не должна превзойти практичность.

1 голос
/ 08 марта 2011

Если я правильно понимаю ваш вопрос, вот одно из решений: Вы можете вызвать AsEnumerable () для любого IQueryable, и последующие операции будут использовать реализацию Enumerable (LINQ to Objects) вместо версии Queryable.

Я написал о многих деталях здесь, в MSDN: http://msdn.microsoft.com/en-us/vcsharp/ff963710

0 голосов
/ 25 октября 2012

Вы можете создать оболочку для результата IQueryable, чтобы разрешить только подкачку и сортировку. Нечто подобное объяснено в этой статье . Но я бы предложил объединить два предложенных интерфейса (ISortable и IPageable) в одну оболочку.

0 голосов
/ 08 марта 2011

Однажды я сталкивался с подобной проблемой и написал об этом в блоге здесь

Ваша ситуация не совсем та же, но концепции и ограничения шаблона Repository.

По сути, я решил заменить шаблон хранилища шаблоном объекта запроса.Объект запроса содержал параметры для фильтрации, сортировки и разбиения по страницам, затем на уровне обслуживания был обернут вокруг IQueryable.

Таким образом, у меня был согласованный интерфейс между моим контроллером и уровнем обслуживания, который не нужно было бы менять, если быЯ изменил хранилища данных (что если в будущем вы отойдете от хранилища с LINQ-упаковкой?) И контролировал, сколько из IQueryable будет выставлено.

...