Вопрос

Я использую 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();

Когда я запускаю свой интеграционный тест, по сути, я создаю нового человека и группу.Добавление группы к человеку.GroupsOwned.Если я получу объект Person обратно из репозитория, GroupsOwned будет равен начальной группе, однако, когда я получу группу обратно, если я проверю count в Group .Администраторы, количество равно 0.В таблице объединения сохранены groupId и PersonID.

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

Это было полезно?

Решение

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

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

Другие советы

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

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

Вы обязательно добавляете Человека в Группы.Администратор?Вы должны создать обе ссылки.

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top