FluentNHibernate和Enums

时间:2009-06-11 00:35:30

标签: nhibernate fluent-nhibernate enums nhibernate-mapping mapping

我有一个名为Permissions的枚举。可以为用户分配权限,或者可以将权限分配给角色,并且可以为用户授予角色。

用户和角色都有这样的属性:

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

我想使用enum for Permissions,所以在我的代码中我可以做像

这样的事情
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)
)

然后,我有权限,以便我需要它,但我只是不知道如何将RolePermissions或Permissions表中的id字段映射回枚举。

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

    CONSTRAINT PK_Permissions PRIMARY KEY CLUSTERED (PermissionId)
)
  1. 我可以将枚举映射到表格吗?
  2. 我是否应该映射它,或者我应该只取出Permissions表,在UserPermissions和RolePermissions中将PermissionId留下一个int并将其映射到枚举?
  3. 如果我保留Permissions表,nhibernate是否有办法从枚举表中的数据中自动填充Permissions表中的数据?
  4. 现在,我没有映射到权限枚举,除了这样的内容:

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

    不幸的是,这会导致错误:

      

    表中的关联   RolePermissions是指未映射的   类:   GotRoleplay.Core.Domain.Model.Permission

    我对枚举的错误是什么?当枚举是对象上的值列表而不仅仅是单个值时,是否有标准方法或最佳实践与fluentnhibernate一起使用?

2 个答案:

答案 0 :(得分:0)

为了确保我理解,您是否尝试将类中的枚举属性映射到数据库中的字段?如果就是这样,那么这是一个如何做到这一点的例子:

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枚举一样使用Condition属性获取,设置和执行逻辑。

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

在Condition字段的数据库中,它应该是一个int。我希望这有意义并回答你的问题。对不起,如果没有,我就走了。

编辑: 对不起,我刚刚注意到你问了这个问题,有些人给了你和我一样的答案。我认为我不能帮助你。 :(

答案 1 :(得分:0)

因此,在与其他开发人员交谈几天后,在网上挖掘并发布到谷歌上的FluentNHibernate小组后,我发现目前并不完全支持枚举的集合。如果有办法做我想做的事情,那么,它没有记录或解决方法。

所以,我带着我正在做的事情回到了绘图板并真正想到了它。基本上,我唯一的选择是使用一个类来获取我的权限。但是,我想在代码中使用我的枚举,那就是它击中了我。 PermissionId字段可以从int转换为枚举,反之亦然。另外,使用我在使用内置ASP.NET提供程序的角色枚举之前所做的一些逻辑,我可以编写一个管理工具,它将根据我的枚举中的内容构建权限。

首先,我重命名了我的枚举。

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,
    }

然后,我创建了一个新的Permission类。此类镜像数据库,只是一个int Id和一个字符串名称。但是,我添加了一个属性来将该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;
            }
        }
    }

然后,在我的User和Role对象中,我引用了Permission,我仍然可以像bool UserHasPermission(PermissionCode.DeleteUser)那样进行匹配;

然后在global.asax中,在Application_Start上,我将检查webconfig是否有标志,指示是否需要重建权限。这样我只有在需要时才能启用重建,而无需进入并可能需要处理错误。这意味着我只在我的枚举中维护一个权限列表,这是理想的。

当然,整体方法并不像我想的那样光滑,但它有效。有没有人有任何其他建议?