NHibernate Join Query with only one instance of QueryOver and no mapping relation defined
NHibernate Join Query with only one instance of QueryOver and no mapping relation defined
就我而言,我只有一个特定的存储库。让我们说“StudentRepository”。这个存储库对我隐藏了 ISession 实例,我唯一拥有的是 IQueryOver< Student,Student> 实例。
考虑以下实体与 NHibernate 的简单映射。
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;}
}
你是对的,基本方法只是将真实关系添加到考试 class,例如:
public Student Student {get; set;}
不幸的是,这也不是一个选择
问题:我需要在 studentRepository 的考试实体上使用 "Score>70" 等条件进行查询。我如何在不知道会话并且没有在映射上定义关系的情况下使用 Nhibernate 生成这样的查询。 ?
所以我认为这里的主要问题是:要使用 QueryOver 连接到不相关的实体,需要将别名定义为根查询的变量(您的 QueryOver 用于学生)。
NHibernate QueryOver to join unrelated entities
中解释了如何进行此类联接
因此,如果您可以修改存储库 class 以允许为此 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();
就我而言,我只有一个特定的存储库。让我们说“StudentRepository”。这个存储库对我隐藏了 ISession 实例,我唯一拥有的是 IQueryOver< Student,Student> 实例。 考虑以下实体与 NHibernate 的简单映射。
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;}
}
你是对的,基本方法只是将真实关系添加到考试 class,例如:
public Student Student {get; set;}
不幸的是,这也不是一个选择
问题:我需要在 studentRepository 的考试实体上使用 "Score>70" 等条件进行查询。我如何在不知道会话并且没有在映射上定义关系的情况下使用 Nhibernate 生成这样的查询。 ?
所以我认为这里的主要问题是:要使用 QueryOver 连接到不相关的实体,需要将别名定义为根查询的变量(您的 QueryOver 用于学生)。 NHibernate QueryOver to join unrelated entities
中解释了如何进行此类联接因此,如果您可以修改存储库 class 以允许为此 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();