我有两个NHibernate实体,它们具有一对一的关系。我们称他们为狗和主人。
public class Dog
{
public virtual int Id { get;set; }
public virtual Owner Owner { get; set; }
}
public class Owner
{
public virtual int Id { get; set; }
public virtual Dog Dog { get; set; }
}
Dog可能拥有一个或零个拥有者。 Fluent / NHibernate映射如下:
public class DogMap : ClassMap<Dog>
{
public DogMap()
{
Table("Dogs");
Id(x => x.Id);
HasOne( x=> x.Owner)
.Fetch.Join()
.Not.LazyLoad();
}
}
public class OwnerMap : ClassMap<Owner>
{
public OwnerMap()
{
Table("Owners");
// Owners share the same primary-key as dogs
Id(x => x.Id).GeneratedBy.Foreign("Dog");
References( x => x.Dog)
.Unique()
.Not.LazyLoad();
}
}
现在我只想选择没有所有者的狗。
我假设查询是:
Owner owner = null;
var ownerlessDogs = session
.QueryOver<Dog>()
.Left.JoinAlias(x => x.Owner, () => owner)
// Restrict on alias
.WhereRestrictionOn(() => owner).IsNull
.List();
但是你可能已经猜到了,这不起作用。它抛出'对象引用未设置为...'。
如果我试试,
var ownerlessDogs = session
.QueryOver<Dog>()
.Left.JoinAlias(x => x.Owner, () => owner)
// Restrict on property of root object
.WhereRestrictionOn(x => x.Owner).IsNull
.List();
它生成基本生成
SELECT {{relevant columns}}
FROM Dogs dogs
LEFT OUTER JOIN OWNERS owners
WHERE dogs.Id IS NULL
几乎是正确的,但它是对狗的主键过滤,而不是对所有者的外键进行过滤。
答案 0 :(得分:4)
在an old post in the Hibernate forum的帮助下,我找到了解决方案:
public class DogMap : ClassMap<Dog> {
public DogMap() {
Table("Dogs");
Id(x => x.Id);
HasOne( x=> x.Owner)
.Fetch.Join();
}
}
public class OwnerMap : ClassMap<Owner> {
public OwnerMap() {
Table("Owners");
//owners share the same primary-key as dogs
Id(x => x.Id).GeneratedBy.Foreign("Dog");
//both sides should be mapped as HasOne
HasOne( x => x.Dog)
.Constrained()
.Fetch.Join();
}
}
工作查询
var ownerlessDogs = session
.QueryOver<Dog>()
.Left.JoinAlias(x => x.Owner, () => owner)
//this is the trick, restrict on Id
.WhereRestrictionOn( x => x.Owner.Id ).IsNull
.List();