代码之家  ›  专栏  ›  技术社区  ›  Ryan Lanciaux

流畅的多对多

  •  22
  • Ryan Lanciaux  · 技术社区  · 16 年前

    我使用的是流利的NHibernate,在与我的一个班级建立多对多的关系时遇到了一些问题。这可能是一个愚蠢的错误,但我有一点被卡住了,试图让它工作。不管怎样,我有几个班级有很多关系。

    public class Person
    {
        public Person()
        {
            GroupsOwned = new List<Groups>();
        }
    
        public virtual IList<Groups> GroupsOwned { get; set; }
    }
    
    public class Groups
    {
        public Groups()
        {
            Admins= new List<Person>();
        }
    
        public virtual IList<Person> Admins{ get; set; }
    }
    

    地图看起来像这样

    人:…

    HasManyToMany<Groups>(x => x.GroupsOwned)
        .WithTableName("GroupAdministrators")
        .WithParentKeyColumn("PersonID")
        .WithChildKeyColumn("GroupID")
        .Cascade.SaveUpdate();
    

    组:…

     HasManyToMany<Person>(x => x.Admins)
        .WithTableName("GroupAdministrators")
        .WithParentKeyColumn("GroupID")
        .WithChildKeyColumn("PersonID")
        .Cascade.SaveUpdate();
    

    当我运行集成测试时,基本上我正在创建一个新的人和组。将组添加到person.groupsowed。如果我从存储库中获取Person对象,则所创建的组等于初始组,但是,如果我检查group.admins上的count,则当我获取组时,计数为0。联接表中保存了groupid和personid。

    谢谢你的建议。

    4 回复  |  直到 12 年前
        1
  •  39
  •   Joel Verhagen    12 年前

    它向表中添加两个记录的事实看起来您缺少一个 inverse attribute . 由于这个人和这个群体都在被改变,所以NHibernate两次坚持这种关系(每个对象一次)。反转属性专门用于避免这种情况。

    我不知道如何在代码中的映射中添加它,但是链接显示了如何在XML中添加它。

        2
  •  7
  •   Rap    14 年前

    @圣地亚哥,我认为你是对的。

    答案可能只是你需要删除许多声明中的一个,看得更流利,看起来它可能足够聪明,只为你做。

        3
  •  0
  •   emeryc    16 年前

    您确定要将此人添加到groups.admin吗?你必须建立两个链接。

        4
  •  0
  •   emeryc    16 年前

    你有三张桌子,对吗?

    人员、组和组管理员

    当你加入到两边,你会得到

    人(ID为p1) 组(ID为g1)

    在GroupAdministrators中,有两列和一个表

    (P1,G1)

    (P1,G1)

    您的单元测试代码如下所示。

    Context hibContext //Built here
    Transaction hibTrans //build and start the transaction.
    
    Person p1 = new Person()
    Groups g1 = new Groups()
    
    p1.getGroupsOwned().add(g1)
    g1.getAdmins().add(p1)
    
    hibTrans.commit();
    hibContext.close();
    

    然后在你的测试中,你做了一个新的上下文,测试看看上下文中是什么,你得到了正确的东西,但是你的表都被弄脏了?