NHibernate коллекция Count () дилемма - PullRequest
0 голосов
/ 29 июня 2011

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

В некоторых ситуациях мне приходится проверять количество элементов коллекции в моемслужебная логика.

Пример:

EventService eventService=container.Resolve<EventService>();
IEnumerable<Event> events=eventService.GetAll();
if(events.Count()>0)
{
    ...do something...
}

При использовании NHibernate это автоматически сгенерирует оператор SQL с доступом к БД из моего класса репозитория.

Можно ли этого избежать?Есть ли лучшая практика?

Ответы [ 2 ]

4 голосов
/ 29 июня 2011

Я стараюсь не выставлять IQueryable<T> в репозитории по следующим причинам:

  • Многие методы или не поддерживаются, и не всегда ясно, какой тип запроса будет сгенерирован.
  • Поддержка специальных запросов подрывает важность разработки правильных индексов для конкретных случаев использования.
  • Вы теряете спецификацию ожидаемых запросов.

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

В частности, для этого случая у меня будет метод длярепозиторий, возвращающий список событий с нумерацией страниц:

IList<Event> GetAll(int startIndex, int count);

Это также подчеркивает важность нумерации страниц.В хранилище это может выглядеть примерно так:

this.Session.Linq<Event>().Skip(startIndex).Take(count).ToList();

Вы также можете создать объект обтекания для IList, который также может содержать общее количество.

1 голос
/ 29 июня 2011

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

Таким образом, когда вы вызываете Count (), он возвращает счетчик вашего статического списка, что вы можете надежно утверждать.

Обновление

Моя ошибка, я предположил из этой строки

Я должен проверить количество элементов коллекции в моей служебной логике

ТоВы хотели проверить эту логику своей службы.

Ваш приведенный выше код выглядит так, как будто вы возвращаете IQueryable.Поэтому, как только вы позвоните по номеру Count() или ToList() (по сути, ко всему, что перечисляет IQueryable), вы попадете в базу данных.

Так что либо измените службу, чтобы она вернула IList<T>, либо измените код, указанный ниже:

EventService eventService=container.Resolve<EventService>(); 
IEnumerable<Event> events = eventService.GetAll().ToList(); 
if(events.Count()>0) {     ...do something... } 

Вы попадете в базу данных при вызове ToList(), но не при вызове Count(), когда работаете с коллекцией в памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...