查询对不同类的限制比返回类

对于我目前的项目,我正在学习NHibernate,我在翻译下面的查询时遇到了麻烦

select person.Firstname, person.Lastname from Person inner join Contract on contract.PersonId = person.Id inner join Budget on budget.ContractId = contract.Id inner join Choice on choice.BudgetId = budget.Id inner join ChosenBenefit on ChosenBenefit.ChoiceId = choice.Id where ChosenBenefit.BenefitImplementationId = 77 

我认为下面的方法可以解决问题,但是我得到了一个无法使用堆栈跟踪的无效引用。

 Choice choice = null; Budget budget = null; Contract contract = null; Person person = null; var peopleThatChose = Session.QueryOver() .JoinAlias(chosenBenefit => chosenBenefit.Choice, () => choice) .JoinAlias(chosenBenefit => choice.Budget, () => budget) .JoinAlias(chosenBenefit => budget.Contract, () => contract) .JoinAlias(chosenBenefit => contract.Person, () => person) .Where(chosenBenefit => chosenBenefit.BenefitImplementation.Id == 77) .Select(benefit => person); 

从各地的所有例子来看,我认为它应该是QueryOver ,但是我无法按照我想要限制的方式工作。

我错过了什么?

假设有关映射的一些事情,我很确定你可以在没有子查询的情况下做到这一点:

 Person person = null; var peopleThatChose = Session.QueryOver(() => person) .JoinQueryOver(person => person.Contracts) .JoinQueryOver(contract => contract.Budget) .JoinQueryOver(budget => budget.Choice) .JoinQueryOver(choice => choice.ChosenBenefit) .Where(chosen => chosen.BenefitImplementation.Id == 77) .SelectList(list => list .Select(() => person.FirstName) .Select(() => person.LastName)) .List(); 

如果我确实正确地读了你的模型:一个Person可以有更多的合同(contract.PersonId) 。 那么在这种情况下我们要做的是将查询分成两部分。

  1. 子查询,从合同中获取PerosnId(按福利过滤)和
  2. Person外部查询仅检索人员…

1)子查询

  var subquery = Session.QueryOver() // the path from Benefit to Contract is the same .JoinAlias(chosenBenefit => chosenBenefit.Choice, () => choice) .JoinAlias(chosenBenefit => choice.Budget, () => budget) .JoinAlias(chosenBenefit => budget.Contract, () => contract) // we do filter over choosen benefit, to get correct contracts .Where(chosenBenefit => chosenBenefit.BenefitImplementation.Id == 77) // lets select the PerosnId from a contract .Select(benefit => contract.PersonId); 

2)现在我们将查询Person,并使用子查询结果进行过滤(在DB服务器上)

 var peopleThatChose = session.QueryOver() .WithSubquery .WhereProperty(p => p.Id) .In(subquery); 

那么,我们做了什么:

  • 我们使用了从ChoosenBenefitContract …的ChoosenBenefit导航来获取PersonId
  • 我们用结果过滤了纯Person查询,现在我们甚至可以对Person实体进行正确的Paging(Take(),Skip())