C# 如何在nHibernate中部分投影具有多个字段的子对象
我有下面的nHibernate查询,它根据课程id选择课程,然后在初始获取时为课程对象返回所选字段,查询执行时没有问题C# 如何在nHibernate中部分投影具有多个字段的子对象,c#,nhibernate,C#,Nhibernate,我有下面的nHibernate查询,它根据课程id选择课程,然后在初始获取时为课程对象返回所选字段,查询执行时没有问题 MatchMode option = ... CourseItem courseAlias = null; TeacherItem teacherAlias = null; var query = session.QueryOver<CourseItem>() .JoinAlias(c => c.Teacher, () => teacher
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>();
MatchMode选项=。。。
CourseItem courseAlias=null;
TeacherItem teacherAlias=null;
var query=session.QueryOver()
.JoinAlias(c=>c.Teacher,()=>teacherAlias)
.Where(c=>c.CourseID.IsInsensitiveLike(strNumber,选项))
.SelectList(list=>list
.Select(c=>c.CourseID).WithAlias(()=>courseAlias.CourseID)
.Select(c=>c.IsActive)。使用别名(()=>courseAlias.IsActive)
.Select(c=>c.CourseDesc)。使用别名(()=>courseAlias.CourseDesc)
.Select(c=>c.Teacher).with别名(()=>courseAlias.Teacher))
.TransformUsing(Transformers.AliasToBean())
.List();
我想进一步查询,只返回部分教师对象,假设我只想返回ID和名称。因此,我将预计名单更新如下:
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>();
var query=session.QueryOver()
.JoinAlias(c=>c.Teacher,()=>teacherAlias)
.Where(c=>c.CourseID.IsInsensitiveLike(strNumber,选项))
.SelectList(list=>list
.Select(c=>c.CourseID).WithAlias(()=>courseAlias.CourseID)
.Select(c=>c.IsActive)。使用别名(()=>courseAlias.IsActive)
.Select(c=>c.CourseDesc)。使用别名(()=>courseAlias.CourseDesc)
.Select(c=>c.Teacher.ID).with别名(()=>courseAlias.Teacher.ID)
.Select(c=>c.Teacher.Name).with别名(()=>courseAlias.Teacher.Name))
.TransformUsing(Transformers.AliasToBean())
.List();
查询不起作用,因为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[]>();
var query=session.QueryOver(()=>courseAlias)
.JoinAlias(()=>courseAlias.Teacher,()=>teacherAlias)
.Where(()=>courseAlias.CourseID.IsInsensitiveLike(strNumber,选项))
.SelectList(list=>list
.选择(()=>courseAlias.CourseID)
.选择(()=>courseAlias.IsActive)
.选择(()=>courseAlias.CourseDesc)
.选择(()=>teacher.ID)
.选择(()=>teacher.Name))
.List();
我可以查询正确的值,但无法将其正确转换回课程/教师数据类型
有什么想法吗
谢谢 我们确实可以使用定制变压器。有一个,我正在使用它进行非常非常深的投影(包括动态对象-)
// 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>())
//只是最后几行不同
var query=session.QueryOver()
.JoinAlias(c=>c.Teacher,()=>teacherAlias)
.Where(c=>c.CourseID.IsInsensitiveLike(strNumber,选项))
.SelectList(list=>list
.Select(c=>c.CourseID).WithAlias(()=>courseAlias.CourseID)
.Select(c=>c.IsActive)。使用别名(()=>courseAlias.IsActive)
.Select(c=>c.CourseDesc)。使用别名(()=>courseAlias.CourseDesc)
//本机WitAlias无法工作,它使用表达式
//仅提取最后一个属性
//.Select(c=>c.Teacher.ID).with别名(()=>courseAlias.Teacher.ID)
//.Select(c=>c.Teacher.Name).with别名(()=>courseAlias.Teacher.Name))
//因此,我们可以使用这种方式传递深层别名
.Select(Projections.Property(()=>teacherAlias.ID).As(“Teacher.ID”))
.Select(Projections.Property(()=>teacherAlias.Name).As(“Teacher.Name”))
//而不是这个
//.TransformUsing(Transformers.AliasToBean())
//用这个
.TransformUsing(新的DeepTransformer())
如果您的别名与属性名称匹配,那么转换器将构建对象树…这可能会有所帮助(请参阅“创建您自己的转换器”),但您是否可以使用另一个POCO或DTO将查询结果投影到?通常,这样的查询最适合填充用于特定任务的特定类型是-这是一种可能性,或者使用fetch而不是投影属性来加载整个子对象。我想主要的问题是子对象有很多字段,如果我的父对象列表很大,它的性能会受到影响。。dictionary.Is()-这是扩展方法吗?如果是,它应该做什么?是的;);)很抱歉似乎如此;)它应该是
。IsNull()
代表==null
,。is()
是!=空
;)你们知道这是“写进语言…”(JavaScript也可能是一样的…)很棒的地方。我真的没有意识到!谢谢-我会试试。这是一个非常好的解决方案,你应该写一篇关于这个的博文!!如果这对你有所帮助,我真的很兴奋。享受精彩的NHibernate:)