2008-12-12 9 views
6

Estoy trabajando con NHibernate y necesito recuperar y procesar hasta 2 millones de filas. Idealmente, podría procesar cada fila, una a la vez, sin NHibernate cargando los 2 millones en memoria a la vez (porque, ya sabes, eso duele).¿Es posible obtener un IEnumerable perezoso de una consulta de NHibernate usando ICriteria?

Preferiría obtener un IEnumerable que llamaría iterativamente al lector de datos para cada lectura, así podría procesar la lectura de datos y luego descartarla. Al hacerlo de esta manera, guardo una gran cantidad de memoria y comienzo a procesar los resultados mucho más rápido. También podría mejorar el rendimiento a través de subprocesos múltiples y/o el uso de PLinq.

¿Esto es posible con NHibernate's ICriteria? Todo lo que devuelve parece ser IList y completamente cargado antes de entregar la referencia de recopilación. ¿Por qué IList en lugar de IEnumerable?

No me refiero a "perezoso" en el sentido tradicional que NHibernate usa con respecto a la carga de objetos secundarios o secundarios. Quiero un perezoso IEnumerable que significa de alguna manera obtener un IEnumerable de un objeto de ICriteria. ICriteria solo tiene un método List() que carga los resultados en una ArrayList.

+0

Pensé que cuando hacía un IEnumerable perezoso en NHibernate comenzaba a consultar la base de datos una fila a la vez. Puede ser más fácil bajar al lector de datos de ADO.Net si tiene que lidiar con tantas filas. – Min

Respuesta

1

ICriteria no tiene ningún método que devuelva IEnumerable, pero IQuery does.

+0

¿hay alguna forma de transformar un ICriteria en un IQuery? – TheSoftwareJedi

+0

AFAIK IQuery es para HQL y SQL (consultas basadas en cadenas) e ICriteria es ... bueno, Criteria, no veo ningún puente entre los dos. Me parece extraño que ICriteria no implemente un Enumerate ... –

+0

Yo también. Estoy usando el código Linq-NHibernate de NContrib, e implementan usando un ICriteria (después de mirar su código).Trataré de arreglar su mierda. Alguna idea de cuándo NHibernate apoyará a Linq oficialmente (sé que los comienzos están ahí). – TheSoftwareJedi

0

Lo que se quiere hacer es envolver su acceso a datos en un método de este modo:

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

No tengo VS o NHibernate útil ahora, lo siento por código semi-seudo. Pero la clave aquí es usar "rendimiento de retorno".

+0

Creo que la declaración de ejecución de NHibernate hace que no sea Lazy como la OP quería. – user7116

+0

Cuando OP dijo LAZY, creo que quiso decir algo como lo que hace el SqlDataReader. – Strelok

+0

Esto es lo que quiero, pero quiero saber cómo hacer NHibernate para mí, o al menos apoyarlo. NHibernate me entrega una IList ... En realidad, uso Linq para NHibernate (de NContrib), pero eso no parece importar ... – TheSoftwareJedi

0

¿Qué tipo de operación es que tiene que hacerlo fila por fila? Tengo curiosidad :).

Puede tratar de buscar los resultados en la página, obtenga los primeros 10, los 10 siguientes ... y así sucesivamente.

EDIT: por lo que tendría

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>(); 

se obtiene la imagen, supongo que no es la mejor manera, no es IEnumerable ... pero funcionaría. También podría hacer SetMaxResults (10) o algo más grande, para no enviar 1 a la vez.

+0

¿Cómo puedo buscar los resultados? Lo que estoy haciendo es transmitir los resultados a un cliente HTTP como un archivo CSV. Ya implementé CSVStream y admitiría convertir y escribir un registro a la vez. Solo necesito que NHibernate también lo haga. DE ICRITERIA. :) – TheSoftwareJedi

+0

No hay un método para obtener un IEnumerable de ICriteria. –

Cuestiones relacionadas