3

У меня есть перечисление под названием Разрешения. Пользователю могут быть назначены разрешения, или разрешения могут быть назначены роли, и пользователю может быть предоставлена ​​роль.FluentNHibernate и Enums

пользователя и роль оба имеют свойство так:

public virtual IList<Permission> Permissions { get; set; } 

Я хочу использовать перечисление для разрешения, чтобы в моем коде я могу делать вещи, как

public static bool UserHasPermission(Permission.DeleteUser) 

Прямо сейчас у меня есть около 50 разных разрешений в моем перечислении. Было бы неплохо, если бы мне не пришлось заполнять набор данных зеркал в базе данных. Мое перечисление выглядит следующим образом:

public enum Permission 
    { 
     //site permissions 1-99 
     [StringValue("View Users")] 
     ViewUser = 1, 

     [StringValue("Add User")] 
     AddUser = 2, 

     [StringValue("Edit User")] 
     EditUser = 3, 

     [StringValue("Delete User")] 
     DeleteUser = 4 

     ... 

} 

В настоящее время у меня есть таблица разрешений, что является PermissionId (INT) и PermissionName (VARCHAR (50)).

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

CREATE TABLE dbo.Roles 
(
    RoleId      int     IDENTITY(2,1) NOT NULL, 
    RoleName     varchar (50)  NOT NULL, 

    CONSTRAINT PK_Roles PRIMARY KEY CLUSTERED (RoleId) 
) 

CREATE TABLE dbo.RolePermissions 
(
    RolePermissionId   int     IDENTITY(1,1) NOT NULL, 
    RoleId      int     NOT NULL, 
    PermissionId    int     NOT NULL, 

    CONSTRAINT PK_RolePermissions PRIMARY KEY CLUSTERED (RolePermissionId), 
    CONSTRAINT FK_RolePermissions_Roles FOREIGN KEY (RoleId) REFERENCES Roles(RoleId), 
    CONSTRAINT U_RolePermissions UNIQUE(RoleId, PermissionId) 
) 

Тогда, у меня есть разрешения TBLE в случае мне это нужно, но я просто не понимаю, как отобразить либо поле идентификатора в RolePermissions или таблицу разрешений обратно в перечисление.

CREATE TABLE dbo.Permissions 
(
    PermissionId     int     NOT NULL, 
    PermissionName     varchar (50)  NOT NULL, 

    CONSTRAINT PK_Permissions PRIMARY KEY CLUSTERED (PermissionId) 
) 
  1. Могу ли я сопоставить перечисление в таблицу?
  2. Должен ли я отображать его, или я должен просто вынуть таблицу разрешений, а в UserPermissions и RolePermissions оставить PermissionId только int и нанести карту на enum?
  3. Если я сохраняю таблицу разрешений, есть ли способ, чтобы nhibernate мог автопопулировать данные в таблице разрешений из данных в перечислении?

Прямо сейчас, у меня нет отображения на разрешение перечисления, кроме чего-то вроде этого:

HasManyToMany(x => x.Permissions) 
       .WithParentKeyColumn("RoleId") 
       .WithChildKeyColumn("PermissionId") 
       .WithTableName("RolePermissions") 
       .LazyLoad() 
       .Cascade.All(); 

К сожалению, это приводит к ошибке:

An association from the table RolePermissions refers to an unmapped class: GotRoleplay.Core.Domain.Model.Permission

Что я делаю неправильно с перечислениями? Существует ли стандартный способ или наилучшая практика для их использования с fluentnhibernate, когда перечисление представляет собой список значений объекта, а не только одно значение?

ответ

0

Итак, после нескольких дней разговора с другими разработчиками, копаясь в Интернете и отправляя группу FluentNHibernate в google, я обнаружил, что коллекции перечислений в настоящее время не поддерживаются точно. сделайте то, что я хочу сделать, ну, это недокументированное или обходное решение.

Итак, я вернулся к чертежной доске с тем, что я делал, и действительно подумал об этом. В принципе, мой единственный выбор заключался в том, чтобы использовать класс для мои права.Но я хочу использовать свое перечисление в коде, и это то, когда оно ударило меня. Поле PermissionId может быть преобразовано из int в перечисление и наоборот. Кроме того, используя некоторую логику, которую я делал до этого при использовании перечисления ролей со встроенным поставщиком ASP.NET, я могу написать административный инструмент, который будет строить permis на основе того, что находится в моем перечислении.

Во-первых, я переименовал свое перечисление.

public enum PermissionCode 
    { 
     //site permissions 1-99 
     [StringValue("View Users")] 
     ViewUser = 1, 

     [StringValue("Add User")] 
     AddUser = 2, 

     [StringValue("Edit User")] 
     EditUser = 3, 

     [StringValue("Delete User")] 
     DeleteUser = 4, 
    } 

Затем я создал новый класс разрешений. Этот класс отражает базу данных и представляет собой просто идентификатор int и имя строки. Тем не менее, я добавил одно свойство для преобразования этого id в мое перечисление PermissionCode.

public class Permission 
    { 
     public virtual int PermissionId { get; set; } 
     public virtual string PermissionName { get; set; } 

     public virtual PermissionCode PermissionCode 
     { 
      get 
      { 
       return (PermissionCode)PermissionId; 
      } 
     } 
    } 

Тогда в моих пользователей и ролей объектов, я ссылаться на разрешение, и я все еще могу сделать матчей, как BOOL UserHasPermission (PermissionCode.DeleteUser);

Тогда в global.asax, на Application_Start Я проверю webconfig на флаг, который укажет, нужно ли переустанавливать разрешения. Таким образом, я могу включить восстановление только тогда, когда мне нужно, чтобы у вас не было разрешения на вход и, возможно, было нужно иметь дело с ошибкой. Это означает, что я поддерживаю только один список разрешений в моем перечислении, что идеально.

Конечно, общий подход не такой гладкий, как я хотел, но он работает. У кого-нибудь есть другие предложения?

+1

Я не могу помочь вам с лучшим решением, но я рад, что вы нашли ответ. – CalebHC

0

Просто убедитесь, что я понимаю, вы пытаетесь просто отобразить свойство enum в своем классе для поля в базе данных? Если это так, то вот пример того, как сделать это:

public class Toy { 
    public virtual int Id { get; private set; } 
    public virtual string Name { get; set; } 
    public virtual ToyCondition Condition { get; set; } 
} 

public enum ToyCondition { 
    New, 
    Used 
} 

public class ToyMap : ClassMap<Toy> { 
    public ToyMap() { 
     Id(x => x.Id); 
     Map(x => x.Name); 
     Map(x => x.Condition).CustomTypeIs(typeof(ToyCondition)); 
    } 
} 

После того, что вы можете получить, установить и сделать логику собственности Состояние так же, как нормальный используя ToyCondition ENUM.

Toy newToy = new Toy(); 
newToy.Condition = ToyCondition.New; 
toyRepository.Save(newToy); 

В базе данных для поля Условие должно быть значение int. Надеюсь, это имело смысл и ответило на ваш вопрос. Извините, если это не так, и я ушел.

Редактировать: Извините, я просто заметил, что вы задали этот вопрос, и кто-то дал вам тот же ответ, что и я. Я не думаю, что смогу вам помочь.:(

+0

Моя проблема заключается не в одном экземпляре перечисления. Это список значений. Я не могу сопоставить его так же. CustomTypeIs не используется, когда у вас есть коллекция. – Josh

Смежные вопросы