Свободное отображение NHibernate «многие ко многим» с автоматически генерируемым ПК вместо составного ключа - PullRequest
0 голосов
/ 02 февраля 2010

Я работаю над RoleProvider в .NET, используя Fluent NHibernate для отображения таблиц в базе данных Oracle 9.2.

Проблема в том, что таблица «многие ко многим», связывающая пользователей и роли, использует первичный ключ, сгенерированный из последовательности, а не составной ключ. Я не могу изменить это, потому что я пишу это для реализации в существующей более крупной системе.

Вот моя UserMap:

        public UserMap()
        {
            this.Table("USR");
            HasMany(x => x.Memberships).Cascade.All()
                .Table("MEMBERSHIP").Inverse().LazyLoad();
            HasManyToMany(x => x.Roles)
                .Table("USR_ROLE")
                .Cascade.SaveUpdate()
                .ParentKeyColumn("USR_ID")
                .ChildKeyColumn("ROLE_ID")
                .Not.LazyLoad();
        }

И моя ролевая карта:

    public RoleMap()
    {
        this.Table("ROLE");            
        Map(x => x.Description).Column("ROLE_NAME");
        Map(x => x.Comment).Column("ROLE_COMMENT");
        HasManyToMany(x => x.Users)
            .Table("USR_ROLE")
            .ParentKeyColumn("ROLE_ID")
            .ChildKeyColumn("USR_ID")
            .Inverse();
    }

Тем не менее, это дает мне ошибку:

Тип 'FluentNHibernate.Cfg.FluentConfigurationException' в сборке 'FluentNHibernate, версия = 1.0.0.593, Culture = нейтральный, PublicKeyToken = 8aa435e3cb308880' не помечен как сериализуемый.

Существует ли простое исправление, позволяющее этому HasMayToMany использовать мое расширение PersistentObjectMap? Я думаю, что мне, возможно, придется добавить соглашение для этого отношения «многие ко многим», но я не знаю, с чего начать, так как я только недавно начал использовать NHibernate и Fluent NHibernate.

Я какое-то время работал над этой проблемой и, похоже, не могу найти решение. Любая помощь приветствуется. Спасибо.

РЕДАКТИРОВАТЬ: Я думаю, что я нашел здесь возможное решение: http://marekblotny.blogspot.com/2009/02/fluent-nhbernate-and-collections.html

Я попробую описанный выше метод создания сущности и карты классов для таблицы ссылок и опубликую свои выводы.

РЕДАКТИРОВАТЬ 2: Я создал объект связывания, как упомянуто в сообщении блога выше, и загрузил новейшие двоичные файлы (1.0.0.623).
Это помогло мне обнаружить, что проблема заключалась в настройке отложенной загрузки и попытке добавить роли к объекту пользователя в совершенно новом сеансе.

Я изменил код для перемещения OpenSession в BeginRequest HttpModule, как описано здесь . После этого я изменил свой код доступа к данным с переноса открытого сеанса в оператор использования, который закрывает сеанс после его завершения, на получение текущего сеанса и перенос только транзакции в оператор использования.

Это, похоже, решило большую часть моей проблемы, но сейчас я получаю сообщение об ошибке «Не удалось вставить коллекцию» в таблицу USR_ROLE. И мне интересно, должен ли вышеуказанный код работать с UserRoleMap, описанным как:

    public UserRoleMap()
    {
        this.Table("USR_ROLE"); 

        /* maps audit fields id, created date/user, updated date/user */
        this.PersistentObjectMap("USR_ROLE"); 

        /* Link these tables */
        References(x => x.Role).Column("ROLE_ID");
        References(x => x.User).Column("USR_ID");
    }

Документация Hibernate для отношений «многие ко многим» предлагает создать объект для поддержки «один ко многим / многие к одному», как в ERD. Я уверен, что это будет намного проще с обычными стандартами именования, но я должен придерживаться определенных сокращений и нечетных (и не всегда должным образом реализованных) соглашений.

1 Ответ

0 голосов
/ 09 февраля 2010

Чтобы исправить это, я создал Entity, Mapping и Repository для UserRole. И вместо отображения HasManyToMany в объектах User и Role у меня есть отображение HasMany. Это немного странно, потому что у меня теперь есть:

IList<UserRole> UserRoles {get; protected set;}

и IList<Role> Roles { get{ return UserRoles.Select(u => u.Role).ToList(); } }

Это работает, однако я не уверен на 100%, почему это работает, а HasManyToMany - нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...