我想映射一个Person
对象。
我得到了包含PersonId
、FatherId
和MotherId
字段(以及其他字段)的People
表。最后两个引用PersonId
在同一个表中。
在我的域模型中,我希望有一个Children
只读集合,其他每个Person
都将其FatherId
或MotherId
设置为父级的PersonId
。
一种方法是使用两个HasMany
,并使用FatherId
和MotherId
外键分别映射到FathersChildren
和MothersChildren
集合中,并根据父对象的性别在Children
getter中返回其中一个集合。但可以说,这让我的领域对象变得丑陋。
有没有办法只在映射中解决这个问题?无论是流利的还是hbm,我都会很高兴。
好吧,我在查看我的模型时发现NHibernate需要所有属性都是virtual
才能允许延迟加载。它返回一个对象,该对象具有从原始对象继承的类。所以我也这么做了。
我的域模型保持不变:
public class Person
{
public virtual Guid Id { get; private set; }
public virtual Gender Gender { get; set; }
public virtual IEnumerable<Person> Children { get; set; }
}
用于映射的实体类:
public class PersonEntity : Person
{
public virtual IList<Person> FatherChildren { get; set; }
public virtual IList<Person> MotherChildren { get; set; }
public override IEnumerable<Person> Children
{
get
{
return Gender == Domain.Gender.Male ? FatherChildren : MotherChildren;
}
}
}
并且为派生类稍微修改了映射:
public class PersonMap : ClassMap<PersonEntity>
{
public PersonMap()
{
Table("People");
Id(x => x.Id)
.GeneratedBy.Guid();
HasMany<PersonEntity>(x => x.FatherChildren)
.KeyColumn("FatherId")
.Inverse()
.ReadOnly();
HasMany<PersonEntity>(x => x.MotherChildren)
.KeyColumn("MotherId")
.Inverse()
.ReadOnly();
Map(x => x.Gender);
}
}
现在我有了一个干净的模型!