Свободное владение NHibernate многие-ко-многим

Я использую Fluent 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.GroupsOwned. Если я получу объект Person обратно из репозитория, GroupOwned будет равен исходной группе, однако, когда я верну группу, если я проверю счетчик в Group.Admins, счет будет 0. В таблице Join есть GroupID и В нем сохранен PersonID.

Спасибо за любой совет, который у вас есть.


person Ryan Lanciaux    schedule 20.09.2008    source источник


Ответы (4)


Тот факт, что он добавляет две записи в таблицу, выглядит так, будто вам не хватает обратный атрибут. Поскольку и человек, и группа меняются, NHibernate сохраняет отношение дважды (по одному разу для каждого объекта). Обратный атрибут предназначен специально для того, чтобы этого избежать.

Я не уверен, как добавить это в отображение в коде, но ссылка показывает, как это сделать в XML.

person Santiago Palladino    schedule 20.09.2008

@ Сантьяго, я думаю, ты прав.

Ответ может заключаться в том, что вам нужно удалить одно из ваших объявлений ManyToMany. Если посмотреть на Fluent, похоже, что он может быть достаточно умным, чтобы просто сделать это за вас.

person emeryc    schedule 20.09.2008
comment
Сообщение под этим - правильный ответ. Ему не хватает инверсии. - person Hash; 31.10.2011

Вы обязательно добавляете этого человека в Groups.Admin? Вы должны сделать обе ссылки.

person emeryc    schedule 20.09.2008

У вас есть три стола, верно?

Люди, группы и администраторы групп

когда вы добавляете к обеим сторонам, вы получаете

Люди (с идентификатором p1) Группы (с идентификатором 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();

А затем в своем тесте вы создаете новый контекст и тестируете, чтобы увидеть, что в контексте, и вы получаете то, что нужно, но ваши таблицы все испорчены?

person emeryc    schedule 20.09.2008