就我而言,我只有一个特定的存储库。让我们说“ StudentRepository ”。该存储库向我隐藏了 ISession 实例,而我仅有的是 IQueryOver
class Student
{
public int Id {get;set;}
public string Number {get;set;}
}
class Exam{
public int Id {get;set;}
public double Score {get;set;}
public string StudentNumber {get;set;}
}
您是对的,基本方法是将真正的关系添加到Exam类,例如:
公共学生学生{get;设置;}
不幸的是,这也不是一个选择
问题:我需要在StudentRepository的考试实体上使用“ Score> 70”之类的条件进行查询。如何在不知道会话且映射没有定义关系的情况下使用Nhibernate生成这样的查询。 ?
答案 0 :(得分:1)
所以我看到的主要问题是:要使用QueryOver连接到不相关的实体,必须将别名定义为用于根查询的变量(您的QueryOver用于学生)。 NHibernate QueryOver to join unrelated entities
中说明了如何进行此类连接因此,如果您可以修改存储库类以允许为此QueryOver
提供可选的别名变量,那将是最好的解决方案。这样的事情(我假设您使用的是NHibernate 5.1或更高版本):
Student studentAlias = null;
var studentsQueryOver= yourRepository.GetQueryOver<Student>(studentAlias);
Exam examAlias = null;
var students = studentsQueryOver
.JoinEntityAlias(() => examAlias, () => examAlias.StudentNumber == studentAlias.Number)
.Where(s => examAlias.Score > 70)
.List();
如果不是这样,您仍然可以创建与不相关实体的联接,但是您需要直接使用基础根Criteria
构建它们。像这样:
Exam examAlias = null;
studentsQueryOver.RootCriteria
.CreateEntityAlias(
nameof(examAlias),
Restrictions.EqProperty("examAlias.StudentNumber", studentsQueryOver.RootCriteria.Alias + ".Number"),
JoinType.LeftOuterJoin,
typeof(Exam).FullName);
var students = studentsQueryOver
.Where(s => examAlias.Score > 70)
.List();
在5.1之前的NHibernate版本上,您可以使用子查询:
var subQuery = QueryOver.Of<Exam>()
.Where(e => e.Score > 70)
.Select(e => e.StudentNumber);
subQuery.RootCriteria.Add(Restrictions.EqProperty("StudentNumber", studentsQueryOver.RootCriteria.Alias + ".Number"))
//Or if root query alias variable available simply
//subQuery.And(e => e.StudentNumber == studentAlias.Number)
var students = studentsQueryOver
.WithSubquery.WhereExists(subQuery)
.List();