1 対 1 の関係を持つ 2 つの 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 には所有者が 1 人または 0 人いる場合があります。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 を持たない Dogsを選択したいだけです。
クエリは次のようになると想定しました。
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
ほとんど正しいですが、所有者の犬の外部キーではなく、犬の主キーでフィルタリングしています。