2009-12-15 20 views
9

Estoy tratando de buscar con impaciencia las colecciones con selects, pero todo lo que soy obteniendo es inner se une. Que esta pasando?Forzar una selección entusiasta en NHibernate

Session.CreateCriteria(typeof(Foo)) 
    .SetFetchMode("Bars", FetchMode.Select) 
    .CreateAlias("Bars", "b") 
    .SetFetchMode("b.Bazes", FetchMode.Select) 
    .List(); 

He intentado cambiar fetchMode a Eager, pero eso no quiere trabajar - Me todavía consigo combinaciones internas en lugar de selecciona separadas. No estoy seguro de dónde está obteniendo la unión interna, porque nada en los documentos habla de FetchMode que causa uniones internas. ¿Es posible obtener selecciones ansiosas?

Actualización Bien He pensado que crear un alias provoca una unión interna. Así que puedo usar .CreateAlias ​​("Bars", "b", JoinType.None), pero luego la recuperación de b.Bazes revierte a la carga diferida. Urgh.

Respuesta

1

Una UNIÓN INTERNA es cómo NHibernate cargará sus registros y sus registros secundarios relacionados. Esta es generalmente la forma más eficiente de hacerlo.

Si fuera a utilizar múltiples instrucciones SELECT, la consulta para niños debería incluir de alguna manera los criterios para el elemento primario. Una INNER JOIN hace que sea fácil obtener solo hijos relacionados, NHibernate dividirá esto correctamente en múltiples entidades después de ejecutar la consulta.

Creo que Entity Framework 4 te permitirá hacer múltiples consultas y volver a unir "mágicamente" objetos relacionados, pero no estoy al tanto de que NHibernate tenga esa característica (estoy seguro de que alguien me va a corregir si estoy mal en esto).

+0

Pero el tipo de combinación predeterminado suele ser combinación externa izquierda, ¿no? Las combinaciones internas no funcionan si la clave externa es anulable, o como en mi caso, donde las barras podrían estar vacías. También los documentos parecen indicar que puede hacer una selección entusiasta. – cbp

0
Session.CreateCriteria(typeof(Foo)) 
    .SetFetchMode("Bars", FetchMode.Select) 
    .CreateAlias("Bars", "b") <-- this line triggers a join (think) 
    .SetFetchMode("b.Bazes", FetchMode.Select) 
    .List(); 

Si realmente no quiere que se une puede especificar fetch = "seleccionar" en el mapeo, pero que causaría un N + 1 selecciona que no se recomienda (uno elige para cada entidad Foo, y luego uno para cada Baze)

1

Para nhibernate a las entidades de carga ansiosas se usa la combinación externa izquierda. Así que hay que cambiar el código de la siguiente manera:

Session.CreateCriteria(typeof(Foo)) 
.SetFetchMode("Bars", FetchMode.Select) 
.CreateAlias("Bars", "b", JoinType.LeftOuterJoin) 
.SetFetchMode("b.Bazes", FetchMode.Select) 
.List(); 

Me ayudó en similar scenario.

Cuestiones relacionadas