NHibernate 3.3 Right Join QueryOver一对一关系

本文关键字:一对一 关系 QueryOver Join Right NHibernate | 更新日期: 2023-09-27 18:01:49

情况就是这样。我有一个c#项目,使用NHibernate 3.3(升级不是一个选项),有以下类:

public class Person{
    public List<PersonAddress> PersonAddresses {get;set;}
}
public class NaturalPerson : Person{
    public NaturalProperty NaturalProperty {get;set;}
}
public class LegalPerson : Person{
    public LegalProperty LegalProperty {get;set;}
}
public class Quarantine{
    public Person QuarantinePerson {get;set;}
    public QuarantineProperty QuarantineProperty {get;set;}
}

我需要做的是获得可能或不"处于隔离状态"的人员,并且满足涉及隔离属性,法律或自然属性的不同条件。基本上我需要的是person的左连接,或者是quarantine的右连接:

Select *
From Quarantine q
Right Join Persons p on p.ID = q.QuarantinePersonID
Left Join NaturalPersons np on p.ID = np.ID
Left Join LegalPersons lp on p.ID = lp.ID
Where q.Property = 1
and np.Property = 1

这是我现在拥有的。我已经成功地完成了我需要的"from"子句,但是我在"select"answers"where"子句上遇到了严重的问题:

Person p = null;
Quarantine q = null;
var results = this.Session.QueryOver<Quarantine>(() => q)
                  .JoinQueryOver<Person>(() => q.QuarantinePerson, () => p, JoinType.RightOuterJoin)
                  .SelectList(list => list
                     .Select(() => p.Id))
                  .TransformUsing(Transformers.AliasToBean<Person>())
                  .List<Person>();

这段代码生成如下查询:

`SELECT p1_.PersonID as y0_
FROM   BUP.Quarantines this_
       right outer join BUP.Persons p1_
         on this_.QuarantinePersonID = p1_.PersonID
       left outer join BUP.LegalPersons p1_1_
         on p1_.PersonID = p1_1_.PersonID
       left outer join BUP.NaturalPersons p1_2_
         on p1_.PersonID = p1_2_.PersonID`

正如我所说的,from子句是可以的。现在的问题是Select和Where子句。

Select的主要问题是我需要整个Person对象,无论是法人还是自然人。我已经尝试从查询中删除。selectlist,但它抛出PropertyNotFoundException: "无法在类'Person'中找到属性'p'的setter "。

Where子句的问题是,我不知道如何根据自然人和法人的属性添加条件。筛选隔离和人员属性没有问题,但尚未成功地对其他类执行相同操作。

同样,这个查询应该尽可能高性能,因为超时是一个严重的问题。我已经设法用子查询等其他解决方案,但它们花了太长时间。

任何帮助,任何两个问题,将非常感激!

谢谢! !

NHibernate 3.3 Right Join QueryOver一对一关系

您可以将子查询future混合使用,以便在一行行程中执行两个查询:

var subquery = QueryOver.Of<Quarantine>()
    .Select(x => x.QuarantinePerson.Id);
var naturalPersons = Session.QueryOver<NaturalPerson>()
    .WithSubquery.WhereProperty(x => x.Id).NotIn(subquery)
    //.Where(x => x.NaturalProperty == somehing)
    .Future();
var legalPersons = Session.QueryOver<LegalPerson>()
    .WithSubquery.WhereProperty(x => x.Id).NotIn(subquery)
    //.Where(x => x.LegalProperty == somehing)
    .Future();
var persons = naturalPersons.Cast<Person>().Union(legalPersons);