如何在nHibernate中部分投影具有多个字段的子对象
本文关键字:字段 对象 nHibernate 中部 投影 | 更新日期: 2023-09-27 18:30:13
我有以下nHibernate查询,该查询根据课程id选择课程,然后在初始获取时返回课程对象的选定字段,查询执行时没有问题。
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>();
我想在查询中更进一步,只返回部分教师对象,假设我只想返回ID和Name。因此,我更新了预测列表如下:
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>();
该查询不起作用,因为nHibernate不知道如何基于Teacher.ID和Teacher.Name重新排序。是否可以不将整个子对象提取回父对象?
我已经尝试了下面的查询,它起作用了——这不是我完全想要的结果
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[]>();
我可以查询正确的值,但无法将其正确转换回课程/教师数据类型。
有什么想法吗?
谢谢!
我们确实可以使用自定义转换器。有一个,我正在使用它来进行非常非常深的投影(包括动态对象-5.1.13。组件,动态组件)
DeepTransformer<TEntity>
接受它(如果需要调整它),你的最终查询可能是这样的
// 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>())
如果您的别名与属性名称匹配,则转换器将构建对象树。。。