visual tutorial studio net mvc framework example asp c# nhibernate

c# - tutorial - Cómo proyectar parcialmente un objeto hijo con muchos campos en nHibernate



nhibernate vs entity framework (1)

Tengo la siguiente consulta nHibernate que selecciona un curso en función de 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<CourseItem>() .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<CourseItem>()) .List<CourseItem>();

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

var query = session.QueryOver<CourseItem>() .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<CourseItem>()) .List<CourseItem>();

La consulta no funciona porque nHibernate no tiene idea de cómo redistribuir en función de Teacher.ID y Teacher.Name. ¿Alguna idea sobre si es posible NO recuperar todo el objeto hijo de nuevo a un objeto padre?

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

var query = session.QueryOver<CourseItem>(() => 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<object[]>();

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

¿Alguna idea?

¡Gracias!


De hecho, podemos usar transformadores personalizados. Hay uno, que estoy usando para proyecciones realmente muy muy profundas (incluyendo objetos dinámicos - 5.1.13. Componente, componente dinámico )

  • DeepTransformer<TEntity>

Tómelo (si es necesario, ajústelo) y su consulta final podría ser así

// just the last lines are different var query = session.QueryOver<CourseItem>() .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<CourseItem>()) // use this .TransformUsing(new DeepTransformer<CourseItem>())

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