Можно ли получить ленивый IEnumerable из запроса NHibernate, используя ICriteria? - PullRequest
6 голосов
/ 12 декабря 2008

Я работаю с NHibernate и мне нужно извлечь и обработать до 2 миллионов строк. В идеале я мог бы обрабатывать каждую строку - по одной за раз - без загрузки NHibernate сразу всех 2 миллионов в памяти (потому что, как вы знаете, это больно).

Я бы предпочел получить IEnumerable, который бы вызывал считыватель данных итеративно для каждого чтения, чтобы я мог обработать считанные данные - затем отбросить их. Делая это таким образом, я экономлю нагрузку на память и начинаю обрабатывать результаты намного быстрее. Я мог бы также улучшить производительность за счет многопоточности и / или использования PLinq.

Возможно ли это с помощью ICibereria NHibernate? Все, что он возвращает, кажется IList и полностью загружено перед передачей ссылки на коллекцию. Почему IList вместо IEnumerable?!

Я не имею в виду «ленивый» в традиционном смысле, который NHibernate использует в отношении загрузки дочерних или родительских объектов. Я хочу, чтобы ленивый IEnumerable в некотором смысле означал получение IEnumerable из объекта ICriteria . ICriteria имеет только метод List (), который загружает результаты в ArrayList.

Ответы [ 3 ]

1 голос
/ 12 декабря 2008

ICriteria не имеет методов, возвращающих IEnumerable, но IQuery делает .

0 голосов
/ 12 декабря 2008

Что это за операция, которую нужно делать построчно? Мне просто любопытно:).

Вы можете попытаться просмотреть результаты - получить первые 10, следующие 10 ... и т. Д.

EDIT: Так что вы бы

Session.CreateCriteria(typeof(T)).SetFirstResult(0).SetMaxResults(1).UniqueResult<T>();
Session.CreateCriteria(typeof(T)).SetFirstResult(1).SetMaxResults(1).UniqueResult<T>();
Session.CreateCriteria(typeof(T)).SetFirstResult(2).SetMaxResults(1).UniqueResult<T>();

Вы получаете картину, я думаю, что это не лучший способ, это не IEnumerable ... но это будет работать. Вы также можете сделать SetMaxResults (10) или что-то большее, чтобы не отправлять 1 за раз.

0 голосов
/ 12 декабря 2008

То, что вы хотите сделать, это обернуть ваш доступ к данным таким способом:

public IEnumerable<YourObject> GetALotOfRows() {
  ..execute DataReader
  while(..read..) {
    yield return yourObject;
  }
}

Теперь у вас нет под рукой VS или nHibernate, извините за полупсевдокод. Но ключ здесь заключается в том, чтобы использовать «возврат прибыли».

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