如何在 nHibernate 中部分投影具有多个字段的子对象 [英] How to partially project a child object with many fields in nHibernate

查看:14
本文介绍了如何在 nHibernate 中部分投影具有多个字段的子对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下 nHibernate 查询,它根据课程 ID 选择课程,然后在初始获取时为课程对象返回选定字段,并且查询执行没有问题.

I have the following nHibernate query that select a course based on its course id and then return selected fields for the course object on the initial fetch, and the query executes with no issues.

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 和姓名.因此,我将投影列表更新为如下:

I wanted to go a step further with the query to only return a partial teacher object, let's say i just wanted to return the ID and Name. So, I updated the projected list to as follows:

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 进行解析.关于是否可以不将整个子对象取回父对象的任何想法?

The query doesn't work because nHibernate has no idea how to resovled based on Teacher.ID and Teacher.Name. Any thoughts on whether it's possible to NOT fetch the entire child object back to a parent object?

我已经尝试了以下查询并且它有效,这不是我完全想要的结果

I've tried the following query and it works this is not my fully desired outcome

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[]>();

我可以查询正确的值,但无法将其正确转换回课程/教师数据类型.

I can query the right values but unable to transform it back correctly to the Course / teacher data type.

有什么想法吗?

谢谢!

推荐答案

我们确实可以使用自定义转换器.有一个,我用于非常非常深的投影(包括动态对象 - 5.1.13. 组件,动态组件)

We can indeed use custom transformer. There is one, which I am using for a really very very deep projections (inlcuding dynamic objects - 5.1.13. component, dynamic-component)

接受(如果需要调整它),你的最终查询可能是这样的

Take it (if needed adjust it) and your final query could be like this

// 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>())

如果您的别名确实与属性名称匹配,则转换器将构建对象树...

And in case, that your aliases do match to property names, that transformer will built the object tree...

这篇关于如何在 nHibernate 中部分投影具有多个字段的子对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆