Свободный NHibernate от многих ко многим - PullRequest
22 голосов
/ 20 сентября 2008

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

Спасибо за любые советы.

Ответы [ 4 ]

39 голосов
/ 20 сентября 2008

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

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

7 голосов
/ 20 сентября 2008

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

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

0 голосов
/ 20 сентября 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();

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

0 голосов
/ 20 сентября 2008

Вы уверены, что хотите добавить человека в Groups.Admin? Вы должны сделать обе ссылки.

...