NHibernate самосоединение многие ко многим симметричные отношения (проблема друзей человека) - PullRequest
2 голосов
/ 29 ноября 2009

Есть ли способ настроить симметричное сопоставление отношений самосоединения в NHibernate? Предположим, у нас есть две таблицы:

Users
  id

Relations
  id
  user1
  user2
  relation_type

Классы User и Relation должны выглядеть следующим образом:

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, коллекция Relations пользователя A должна содержать отношение с пользователем B, а отношения пользователя B должны содержать отношение к A.

Звучит почти как вызов. Но может кто-нибудь решить это? Пожалуйста, если можете, опубликуйте карту xml. Я не использую Fluent.

Ответы [ 2 ]

0 голосов
/ 12 января 2010

Я сомневаюсь в этом. Если вы подумаете о ручном SQL-запросе, который вам нужно написать, чтобы вытащить пользователя и все его отношения во внешнем соединении, вы поймете, почему NHibernate будет бороться за создание чего-то подобного. Обновления будут еще большей головной болью - как вы решаете, какие идентификаторы идут в какое поле для нового отношения?

Если вы застряли на этой модели, все, что я могу предложить в качестве обходного пути, - это сопоставить две частные коллекции и внедрить открытую коллекцию Union () только для чтения. Реализуйте методы обновления / удаления, которые находят и изменяют соответствующие отношения, и метод циклического добавления (). У вас не будет поддержки запросов NHibernate для запросов в этой коллекции.

Другой вариант - изменить модель данных таким образом, чтобы пользователь имел отношение многие-ко-многим к Relation (например, таблица UserRelation), полагался на код приложения для обеспечения соблюдения правила «два пользователя на отношение» и добавил удобство такие методы, как IList<User> GetRelations(RelationType)

0 голосов
/ 29 ноября 2009

Вы можете использовать сопоставление Key-Many-To-One и удалить поле Id из сущности отношения. Также вам лучше использовать наследование для разных типов отношений.

...