Cómo proyectar parcialmente un objeto secundario con muchos campos en nHibernate

Tengo la siguiente consulta nHibernate que selecciona un curso basado en su ID de curso y luego devuelve los campos seleccionados para el objeto del curso en la búsqueda inicial, y la consulta se ejecuta sin problemas.

MatchMode option = ... CourseItem courseAlias = null; TeacherItem teacherAlias = null; var query = session.QueryOver() .JoinAlias(c => c.Teacher, () => teacherAlias) .Where(c => c.CourseID.IsInsensitiveLike(strNumber, option)) .SelectList(list => list .Select(c => c.CourseID).WithAlias(() => courseAlias.CourseID) .Select(c => c.IsActive).WithAlias(() => courseAlias.IsActive) .Select(c => c.CourseDesc).WithAlias(() => courseAlias.CourseDesc) .Select(c => c.Teacher).WithAlias(() => courseAlias.Teacher)) .TransformUsing(Transformers.AliasToBean()) .List(); 

Quería ir un paso más allá con la consulta para devolver solo un objeto maestro parcial, digamos que solo quería devolver el ID y el Nombre. Entonces, actualicé la lista proyectada de la siguiente manera:

 var query = session.QueryOver() .JoinAlias(c => c.Teacher, () => teacherAlias) .Where(c => c.CourseID.IsInsensitiveLike(strNumber, option)) .SelectList(list => list .Select(c => c.CourseID).WithAlias(() => courseAlias.CourseID) .Select(c => c.IsActive).WithAlias(() => courseAlias.IsActive) .Select(c => c.CourseDesc).WithAlias(() => courseAlias.CourseDesc) .Select(c => c.Teacher.ID).WithAlias(() => courseAlias.Teacher.ID) .Select(c => c.Teacher.Name).WithAlias(() => courseAlias.Teacher.Name)) .TransformUsing(Transformers.AliasToBean()) .List(); 

La consulta no funciona porque nHibernate no tiene idea de cómo obtener una respuesta basada en Teacher.ID y Teacher.Name. ¿Alguna idea sobre si es posible NO recuperar todo el objeto secundario de nuevo a un objeto principal?

He intentado la siguiente consulta y funciona, este no es mi resultado completamente deseado

 var query = session.QueryOver(() => courseAlias) .JoinAlias(() => courseAlias.Teacher, () => teacherAlias) .Where(() => courseAlias.CourseID.IsInsensitiveLike(strNumber, option)) .SelectList(list => list .Select(() => courseAlias.CourseID) .Select(() => courseAlias.IsActive) .Select(() => courseAlias.CourseDesc) .Select(() => teacher.ID) .Select(() => teacher.Name)) .List(); 

Puedo consultar los valores correctos, pero no puedo volver a transformarlos correctamente en el tipo de datos del curso / profesor.

¿Alguna idea?

¡Gracias!

De hecho, podemos usar un transformador personalizado. Hay uno, que estoy usando para proyecciones realmente muy profundas (incluyendo objetos dynamics – componente 5.1.13 , componente dynamic )

  • DeepTransformer

Tómalo (si es necesario ajústalo) y tu consulta final podría ser así

 // just the last lines are different var query = session.QueryOver() .JoinAlias(c => c.Teacher, () => teacherAlias) .Where(c => c.CourseID.IsInsensitiveLike(strNumber, option)) .SelectList(list => list .Select(c => c.CourseID).WithAlias(() => courseAlias.CourseID) .Select(c => c.IsActive).WithAlias(() => courseAlias.IsActive) .Select(c => c.CourseDesc).WithAlias(() => courseAlias.CourseDesc) // the native WitAlias would not work, it uses expression // to extract just the last property //.Select(c => c.Teacher.ID).WithAlias(() => courseAlias.Teacher.ID) //.Select(c => c.Teacher.Name).WithAlias(() => courseAlias.Teacher.Name)) // so we can use this way to pass the deep alias .Select(Projections.Property(() => teacherAlias.ID).As("Teacher.ID")) .Select(Projections.Property(() => teacherAlias.Name).As("Teacher.Name")) // instead of this // .TransformUsing(Transformers.AliasToBean()) // use this .TransformUsing(new DeepTransformer()) 

Y en caso de que sus alias coincidan con los nombres de las propiedades, ese transformador construirá el árbol de objetos …