我需要一个流利的NHibernate映射,它将实现以下功能(如果没有其他功能,我还将使用适当的NHibernate XML映射并对其进行反向工程)。
细节
我在两个实体之间有一种多对多的关系:
Parent
和
Child
这大概就是我定义类型的方式,至少是相关的部分(其中
Entity
Id
public class Parent : Entity
{
public virtual IList<ParentChildRelationship> Children { get; protected set; }
public virtual void AddChildRelationship(Child child, int customerId)
{
var relationship = new ParentChildRelationship
{
CustomerId = customerId,
Parent = this,
Child = child
};
if (Children == null) Children = new List<ParentChildRelationship>();
if (Children.Contains(relationship)) return;
relationship.Sequence = Children.Count;
Children.Add(relationship);
}
}
public class Child : Entity
{
// child doesn't care about its relationships
}
public class ParentChildRelationship
{
public int CustomerId { get; set; }
public Parent Parent { get; set; }
public Child Child { get; set; }
public int Sequence { get; set; }
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
var other = obj as ParentChildRelationship;
if (return other == null) return false;
return (CustomerId == other.CustomerId
&& Parent == other.Parent
&& Child == other.Child);
}
public override int GetHashCode()
{
unchecked
{
int result = CustomerId;
result = Parent == null ? 0 : (result*397) ^ Parent.GetHashCode();
result = Child == null ? 0 : (result*397) ^ Child.GetHashCode();
return result;
}
}
}
数据库中的表大致如下(假定主键/外键和语法):
create table Parent (
id int identity(1,1) not null
)
create table Child (
id int identity(1,1) not null
)
create table ParentChildRelationship (
customerId int not null,
parent_id int not null,
child_id int not null,
sequence int not null
)
在访问Parent.Children时,NHibernate应该生成一个等价的查询:
SELECT * FROM ParentChildRelationship rel LEFT OUTER JOIN Child ch ON rel.child_id = ch.id WHERE parent_id = ?
好的,我有这样的映射:
ParentMap : ClassMap<Parent>
{
public ParentMap()
{
Table("Parent");
Id(c => c.Id).GeneratedBy.Identity();
HasMany(c => c.Children).KeyColumn("parent_id");
}
}
ChildMap : ClassMap<Child>
{
public ChildMap()
{
Table("Child");
Id(c => c.Id).GeneratedBy.Identity();
}
}
ParentChildRelationshipMap : ClassMap<ParentChildRelationship>
{
public ParentChildRelationshipMap()
{
Table("ParentChildRelationship");
CompositeId()
.KeyProperty(c => c.CustomerId, "customerId")
.KeyReference(c => c.Parent, "parent_id")
.KeyReference(c => c.Child, "child_id");
Map(c => c.Sequence).Not.Nullable();
}
}
所以,在我的测试中,如果我想
myParentRepo.Get(1).Children
parent.Children.Select(r => r.Child).ToList()
).
SELECT * FROM ParentChildRelationship WHERE parent_id = 1
然后是一个
SELECT * FROM Child WHERE id = ?
每段关系中的每个孩子。我理解NHibernate为什么要这样做,但是我不知道如何设置映射以使NHibernate按照我上面提到的方式进行查询。