NHibernate Join Query仅具有QueryOver的一个实例,并且未定义映射关系

时间:2018-11-01 15:17:34

标签: c# join nhibernate fluent-nhibernate

就我而言,我只有一个特定的存储库。让我们说“ StudentRepository ”。该存储库向我隐藏了 ISession 实例,而我仅有的是 IQueryOver 实例。 考虑下面的实体与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;}
}

您是对的,基本方法是将真正的关系添加到Exam类,例如:

  

公共学生学生{get;设置;}

不幸的是,这也不是一个选择

问题:我需要在StudentRepository的考试实体上使用“ Score> 70”之类的条件进行查询。如何在不知道会话且映射没有定义关系的情况下使用Nhibernate生成这样的查询。 ?

1 个答案:

答案 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();