所以,情况就是这样。我有一个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;}
}
我需要做的是获得可能或不“隔离”并且满足涉及隔离区财产以及法律或自然财产的不同条件的人员。基本上我需要的是人员的左连接,或隔离的正确加入:
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”和“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`
正如我所说,“来自”条款是可以的。现在问题在于Select和Where子句。
Select的主要问题是我需要整个Person对象,无论是法人还是自然人。我尝试从查询中删除.SelectList,但它抛出了一个PropertyNotFoundException:“找不到类'Person'中属性'p'的setter”。
Where子句的问题在于我不知道如何根据NaturalPerson和LegalPerson的属性添加条件。我在过滤Quarantine和Person属性方面没有问题,但还没有成功地对其他类做同样的事情。
此外,此查询应尽可能高效,因为超时是一个严重的问题。我已经设法用子查询等方法做了其他解决方案,但是花了太长时间。
任何有关这两个问题的帮助都将非常感谢!
谢谢!
答案 0 :(得分:0)
您可以使用子查询与 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);