2009-11-29 44 views
2

有没有什么办法可以在NHibernate中建立对称的自连接关系映射?假设我们有两个表:NHibernate自加入多对多的对称关系(人朋友问题)

Users 
    id 

Relations 
    id 
    user1 
    user2 
    relation_type 

用户和关系类应该是这样的:

class User 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual ISet<Relation> Relations { get; set; } 
} 

class Relation 
{ 
    public virtual int Id { get; set; } 
    public virtual User User1 { get; set; } 
    public virtual User User2 { get; set; } 
    // Let's leave the RealationType as string for the sake of brevity 
    public virtual string RelationType { get; set; } 
} 

我不想在relations表有两行相同的关系。但是关系必须是对称的,这意味着如果两个用户A和B之间存在关系,则用户A的集合必须包含与用户B的关系,并且用户B的关系必须包含与A的关系。

这听起来像是一个挑战。但是,有人能解决这个问题吗?请,如果可以的话,发布xml映射。我没有使用Fluent。

回答

0

您可以使用Key-Many-To-One映射并从关系实体中删除Id字段。此外,您最好对不同的关系类型使用继承。

+0

好了,这样的话,对于关系的映射将不会停... <类名=“关系”表=“关系”> <复合-ID> <键多对多-one name =“User1”class =“User”/> 我该如何映射用户类?由于id可以在'user1'或'user2'列中。 – svallory 2009-11-29 18:57:18

0

我对此表示怀疑。如果考虑一下你需要编写的手动SQL查询来将外部连接查询中的所有关系都拉出来,你可以看到为什么NHibernate很难生成这样的东西。更新将是一个更大的头痛 - 你如何决定哪个id在新的关系的哪个领域?

如果你被困在这个模型上,我建议作为一个解决方法是映射两个私人收藏并实现一个Union()ed只读公共集合。实现更新/删除方法,找到&修改适当的关系,以及循环法的Add()方法。对于此集合的查询,您不会有任何NHibernate查询支持。

您的其他选择是更改您的数据模型,以便用户与关系具有多对多关系(例如UserRelation表),依靠应用程序代码实施“每个关系两个用户”规则并添加方便的方法,如IList<User> GetRelations(RelationType)