2012-03-15 10 views
10

Tengo esta consulta LINQ simple en NHibernate 3.2 y el proveedor de SQLite:proveedor de LINQ NHibernate y tomar() skip() con recuperación temprana

var all = (from book in Session.Query<Book>() select book) 
    .Skip(15) 
    .Take(15)     
    .ToList(); 

Esta consulta devuelve correctamente 15 entidades, pero cuando intento carga ansiosa una colección de dependencia con FetchMany así:

var all = (from book in Session.Query<Book>() select book) 
    .FetchMany(books => books.Authors) 
    .Skip(15) 
    .Take(15)     
    .ToList(); 

consigo sólo 11 entidades devueltas. ¿Esto es un error o algo que me falta?

Ésta es la consulta SQL resultante

select 
    book0_.Id as Id2_0_, 
    author2_.Id as Id0_1_, 
    book0_.Title as Title2_0_, 
    book0_.Sort as Sort2_0_, 
    book0_.TimeStamp as TimeStamp2_0_, 
    book0_.PubDate as PubDate2_0_, 
    book0_.Series_Index as Series6_2_0_, 
    book0_.Author_Sort as Author7_2_0_, 
    book0_.Isbn as Isbn2_0_, 
    book0_.Lccn as Lccn2_0_, 
    book0_.Path as Path2_0_, 
    book0_.Flags as Flags2_0_, 
    book0_.Uuid as Uuid2_0_, 
    book0_.Has_Cover as Has13_2_0_, 
    book0_.Last_Modified as Last14_2_0_, 
    author2_.Name as Name0_1_, 
    author2_.Sort as Sort0_1_, 
    author2_.Link as Link0_1_, 
    authors1_.book as book0__, 
    authors1_.author as author0__ 
from 
    books book0_ 
    left outer join 
    books_authors_link authors1_ on book0_.Id=authors1_.book left outer join authors author2_ 
    on authors1_.author=author2_.Id 
order by book0_.Id asc 
limit 15 /* @p0 */ offset 0 /* @p1 */ 

Esto limita efectivamente el conjunto de resultados a 15 filas y 15 entidades no como era mi intención hacerlo.

+0

Parece que NHibernate está generando una unión interna cuando debería estar generando una combinación izquierda. Echaré un vistazo adicional a las asignaciones para la propiedad Autores. –

+0

Supongo que este no es el problema porque tengo al menos un autor para cada libro. Y cuando busco a los autores en un bucle foreach para cada libro, obtengo los resultados correctos. – zszep

+0

Lo interesante es que obtengo 15 filas devueltas, pero solo 11 entidades. Dos libros tienen dos autores y un libro tiene tres autores. ¿Estoy en lo correcto al decir que saltar y tomar debería limitar el número de entidades devueltas y no filas? – zszep

Respuesta

12

omitir y tomar se traducen a los equivalentes en sql que limitan en las filas y ya que está ansioso por ir con uniones no hay mucho que pueda hacer al respecto.

a ansiosos buscar a los primeros 15 libros que necesita:

var all = Session.Query<Book>() 
    .Skip(15) 
    .Take(15)     
    .ToList(); 

var ids = all.Select(b => b.Id).ToList(); 

// fetch all Authors of the books, now the books in all have initialized Authors 
Session.Query<Book>() 
    .Where(b => ids.Contains(b.Id)) 
    .FetchMany(books => books.Authors) 
    .List(); 

esto tiene 2 ida y vuelta, aunque

Actualización: uno de ida y vuelta con QueryOver, tal vez usted puede traducirse en LINQ

var subquery = QueryOver.Of<Book>() 
    .Skip(15) 
    .Take(15) 
    .Select(b => b.Id); 

var all = Session.QueryOver<Book>() 
    .WithSubquery.WhereProperty(b => b.Id).In(subquery) 
    .Fetch(books => books.Authors).Eager 
    .ToList(); 
+0

Después de reflexionar sobre el problema, llegué a la misma conclusión, aunque es una pena. Uno esperaría obtener 15 libros cuando especifique take (15) y establezca que Query sea de tipo genérico Book. Traté de construir una instrucción SQL que hiciera esto, pero no podía pensar en una solución. Entonces serán dos consultas, entonces. – zszep

0
var data = session.QueryOver<EmployeeDetails>() 
            .Where(x => x.Salary > 2000) 
            //.Take(2) 
            .Skip(2) 
            .Take(2) 
            .List(); 
       //if take is before skip then it will skip the last (mentioned digits) rows 
       //if take is after skip then it will skip the first (mentioned digits) rows 
Cuestiones relacionadas