NHibernate Mapping для пользовательских ролей и привилегий - PullRequest
1 голос
/ 01 сентября 2009

Сценарий

Я бился головой о стену, пытаясь найти правильное сопоставление для 3 сущностей: Пользователь, Роль и Привилегия. В моем приложении пользователи могут иметь привилегии, которые просто дают пользователю дополнительные разрешения. Пользователи также могут иметь роли, которые по сути являются привилегиями, требующими дополнительных свойств.

Например, пользователь может иметь роль «Администратор приложения», и в этом случае ApplicationAdministratorRole.cs будет нуждаться в свойстве, содержащем список приложений, которыми может управлять пользователь. Пользователь также может иметь привилегию «Администратор событий», и в этом случае Privilege.cs НЕ будет содержать никаких дополнительных свойств для событий, потому что в нашем приложении администратор событий может управлять всеми событиями. Я надеюсь, что этот пример имеет смысл. Если нет, я могу уточнить немного подробнее.

Структура таблицы

[Название таблицы] TBL_USERS

[Столбцы] UserId (PK), Имя, Фамилия, Идентификатор компании, и т.д ...


[Название таблицы] TBL_ROLEREF (просто определяет роли в системе)

[Столбцы] RoleId (PK), RoleName


[Имя таблицы] TBL_USERROLES (таблица для перекрестной ссылки пользователей на роли)

[Столбцы] UserRoleId (PK), Идентификатор пользователя, Идентификатор роли, ActiveDate, DeactiveDate


[Имя таблицы] TBL_APPLICATIONADMINISTRATORS

[Столбцы] ApplicationAdministratorId (PK), ApplicationID, Идентификатор пользователя, Идентификатор роли, ActiveDate, DeactiveDate


[Имя таблицы] TBL_PRIVILEGEREF

[Столбцы] PrivilegeId (PK), PrivilegeName


[Имя таблицы] TBL_USERPRIVILEGES

[Столбцы] UserPrivilegeId (PK), Идентификатор пользователя, PrivilegeId, ActiveDate, DeactiveDate


Структура таблицы довольно проста, все привилегии и роли имеют ActiveDate и DeactiveDate, чтобы мы могли вести историю предыдущих ролей и привилегий пользователей. Следует отметить, что любой роли требуется дополнительная таблица для хранения любой дополнительной информации, которая соответствует этой роли, в этом случае TBL_APPLICATIONADMINISTRATORS будет связывать роль администратора приложений пользователя с различными приложениями из TBL_APPLICATIONREF. Опять, пожалуйста, дайте мне знать, если мне нужно перефразировать это, чтобы лучше понять

Сопоставление файлов

[User.hbm.xml]

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

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Core" namespace="Core">
    <class name="Core.Entities.User, Core" table="TBL_USERS">
        <id name="UserId" column="USERID" type="Int32" unsaved-value="0">
            <generator class="sequence">
                <param name="sequence">SEQ_TBL_USERS</param>
            </generator>
        </id>
        <property name="Title" column="USERTITLE" type="string" length="50" not-null="false" />
        <property name="FirstName" column="USERFIRSTNAME" type="string" length="50" not-null="true" />
        <property name="LastName" column="USERLASTNAME" type="string" length="50" not-null="true" />
        <bag name="Privileges" generic="true" table="TBL_USERPRIVILEGES">
            <key column="USERID" />
            <many-to-many column="PRIVILEGEID" class="Core.Entities.Privilege, Core" />
        </bag>
        <bag name="Roles" generic="true" table="TBL_USERROLES" >
            <key column="USERID" />
            <many-to-many column="ROLEID" class="Core.Entities.Role, Core" />
        </bag>
    </class>
</hibernate-mapping>

[Privilege.hbm.xml]

Объекты привилегий должны иметь PrivilegeId, PrivilegeName, набор пользователей, связанных с привилегией, и ActiveDate / DeactiveDate. Я прокомментировал свои неудачные попытки отобразить это.

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Core" namespace="Core">
    <class name="Core.Entities.Privilege, Core" table="TBL_PRIVILEGEREF">
        <id name="PrivilegeId" column="PRIVILEGEID" type="Int32" unsaved-value="0">
            <generator class="sequence">
                <param name="sequence">SEQ_TBL_USERPRIVILEGES</param>
            </generator>
        </id>
        <property name="Name" column="PRIVILEGENAME" type="string" length="128" not-null="false" />
        <!-- 
        This does not work. NHibernate is complaining about the repeated Column "USERID"
        I have made several attempts to get this to work with no luck... where am I going wrong?
        <bag name="Users" generic="true" table="TBL_USERPRIVILEGES" inverse="true">
            <key column="USERID" />
            <many-to-many column="USERID" class="Core.Entities.User, Core" />
        </bag>
        -->
        <!-- 
        This also does not work. This was my attempt to join the ActiveDate and DeactiveDate into Privilege.cs 
        The join NHibernate creates with this setup is completely wrong... 
        <join table="TBL_USERPRIVILEGES">
            <key column="USERPRIVILEGEID" />
            <property name="ActiveDate" column="ACTIVEDATE" type="DateTime" not-null="false" />
            <property name="DeactiveDate" column="DEACTIVEDATE" type="DateTime" not-null="false" />
        </join>
        -->
    </class>
</hibernate-mapping>

[Role.hbm.xml]

Я хотел бы иметь базовый класс Role, у которого есть свойства для ActiveDate и DeactiveDate, от которых может наследоваться каждая роль (например, ApplicationAdministratorRole), поэтому каждая роль должна иметь эти свойства. Я полагаю, что мог бы также использовать интерфейс, чтобы реализовать это, но это мой первый шаг к отображению чего-то полусложного в NHibernate, поэтому, пожалуйста, дайте мне некоторое руководство по этому вопросу.

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Core" namespace="Core">
    <class name="Core.Entities.Role, Core" table="TBL_ROLEREF">
        <id name="RoleId" column="ROLEID" type="Int32" unsaved-value="0">
            <generator class="sequence">
                <param name="sequence">SEQ_TBL_USERROLES</param>
            </generator>
        </id>
        <property name="Name" column="ROLENAME" type="string" length="128" not-null="false" />
        <bag name="Users" generic="true" table="TBL_USERROLES">
            <key column="ROLEID" />
            <many-to-many column="USERID" class="Core.Entities.User, Core" />
        </bag>
        <joined-subclass name="Core.Entities.ApplicationAdministratorRole, Core" table="TBL_APPLICATIONADMINISTRATORS" extends="Core.Entities.Role, Core">
            <key column="ROLEID" />
            <property name="ApplicationAdministratorId" column="APPLICATIONADMINISTRATORID" type="Int32" />
            <bag name="Applications" generic="true" table="TBL_APPLICATIONREF">
                <key column="APPLICATIONID" />
                <one-to-many class="Core.Entities.Application, Core" />
            </bag>
        </joined-subclass>
        <!-- Do I need to use <join> here to set the ActiveDate and DeactiveDate in the Role base class? -->
    </class>
</hibernate-mapping>

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

Эти файлы сопоставления работают как есть, но они не возвращают правильные результаты. Любая помощь очень ценится.

Спасибо, ребята,

Josh

1 Ответ

3 голосов
/ 01 сентября 2009

Вы пытаетесь отобразить пользователей при использовании USERID дважды, как в качестве ключа, так и в качестве ссылки. Вы, вероятно, имеете в виду:

Я не понимаю этого, какова связь между TBL_PRIVILEGEREF и TBL_USERPRIVILEGES, кажется, нет никакой:

Вы присоединяетесь к отображению подкласса, кажется, прекрасно

...