Mapping a list of Enums

2019-05-14 18:42发布

I have a table called UserPermissions with a FK to the users table by userId and then a string column for the string value of an enum.

The error I am seeing is NHibernate.MappingException: An association from the table UserPermissions refers to an unmapped class: GotRoleplay.Core.Domain.Model.Permission

My Permission Enum:

    public enum Permission
{
    [StringValue("Add User")]
    AddUser,

    [StringValue("Edit User")]
    EditUser,

    [StringValue("Delete User")]
    DeleteUser,

    [StringValue("Add Content")]
    AddContent,

    [StringValue("Edit Content")]
    EditContent,

    [StringValue("Delete Content")]
    DeleteContent,
}

The property in my User class:

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

My database table:

CREATE TABLE dbo.UserPermissions
(
UserPermissionId            int                 IDENTITY(1,1) NOT NULL,
UserId                      int                 NOT NULL,
PermissionName              varchar (50)        NOT NULL,

CONSTRAINT PK_UserPermissions PRIMARY KEY CLUSTERED (UserPermissionId),
CONSTRAINT FK_UserPermissions_Users FOREIGN KEY (UserId) REFERENCES Users(UserId),
CONSTRAINT U_User_Permission UNIQUE(UserId, PermissionName)
)

My attempt at mapping the permissions property of my user object:

HasManyToMany(x => x.Permissions)
             .WithParentKeyColumn("UserId")
             .WithChildKeyColumn("PermissionName")
             .WithTableName("UserPermissions")
             .LazyLoad();

What am I doing wrong that it can't map the permission to a list of enum values?

3条回答
Lonely孤独者°
2楼-- · 2019-05-14 19:16

I thought I would post the code that I chose for my solution. It's only a workaround. I wish Fluent would support Enum lists, but until it does, here's a possible solution:

The Enum - This is my enum, your standard enum.

public enum PermissionCode
{
    //site permissions 1-99
    ViewUser = 1,

    AddUser = 2,

    EditUser = 3,

    DeleteUser = 4
}

Next, I have my Permission class.

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

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

As you can see, I have an ID and a name, and then a property that converts the Id into my PermissionCode enum.

The mapping looks like this:

public class PermissionMap : ClassMap<Permission>
{
    public PermissionMap() 
    {
        WithTable("Permissions");

        Id(x => x.PermissionId).GeneratedBy.Identity();

        Map(x => x.PermissionName);
    }
}

Since the PermissionCode property is derived, we don't do anything in the mapping.

My Table structure behind the mapping looks like this:

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

    CONSTRAINT PK_Permissions PRIMARY KEY CLUSTERED (PermissionId)
)

If you wanted to use the name instead of the integer value, with some slight modifications you can. It depends on your personal preferences.

查看更多
劫难
3楼-- · 2019-05-14 19:37

here is the way which worked for me

HasMany(x => x.Licences)
                .WithTableName("DriverLicence")
                .AsElement("Level").AsBag();

look here for more information answer

查看更多
你好瞎i
4楼-- · 2019-05-14 19:38

You need to specify the type so that NHibernate can convert the value in the table to a member of the Permission enum.

HasManyToMany(x => x.Permissions)
         .WithParentKeyColumn("UserId")
         .WithChildKeyColumn("PermissionName")
         .WithTableName("UserPermissions")
         .LazyLoad()
         .CustomTypeIs(typeof(Permission));

Edited to add: I'm sorry, I should have noticed that you had this as ManyToMany. That's not possible: You can't have a Users collection (other side of m:m) hanging off an enum. You need to define this as 1:m or create a Permission table and class and map that as m:m.

查看更多
登录 后发表回答