【问题标题】:Mapping a list of Enums映射枚举列表
【发布时间】:2010-10-28 09:57:55
【问题描述】:

我有一个名为 UserPermissions 的表,它通过 userId 对用户表进行了 FK,然后是一个字符串列,用于枚举的字符串值。

我看到的错误是 NHibernate.MappingException:来自表 UserPermissions 的关联引用了一个未映射的类:GotRoleplay.Core.Domain.Model.Permission

我的权限枚举:

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

我的用户类中的属性:

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

我的数据库表:

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)
)

我尝试映射用户对象的权限属性:

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

我做错了什么,它无法将权限映射到枚举值列表?

【问题讨论】:

  • 所以经过大量修改后,我最终不得不创建一个名为 UserPermission 的新对象,并将其映射到 UserPermissions 表,并使用我的枚举作为数据类型,并使用 Permission 属性。这很好用,但是权限可以附加到角色和用户,这意味着我的选择查询要获得分配给用户(包括他们的所有角色)的每个权限,需要一组复杂的 linq 语句。我宁愿不那样做。有人有什么想法吗?

标签: fluent-nhibernate enums string mapping


【解决方案1】:

您需要指定类型,以便 NHibernate 可以将表中的值转换为 Permission 枚举的成员。

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

编辑添加: 对不起,我应该注意到你有这个多对多。这是不可能的:你不能让一个用户集合(m:m 的另一端)挂在一个枚举上。您需要将其定义为 1:m 或创建一个 Permission 表和类并将其映射为 m:m。

【讨论】:

  • 我尝试使用您的建议,但 CustomTypeIs 不作为有效选项存在。我尝试改用 .CollectionType(typeof(Permission)) 但我仍然看到相同的错误:来自表 UserPermissions 的关联引用了未映射的类:GotRoleplay.Core.Domain.Model.Permission
【解决方案2】:

我想我会发布我为我的解决方案选择的代码。这只是一种解决方法。我希望 Fluent 支持 Enum 列表,但在它支持之前,这是一个可能的解决方案:

枚举 - 这是我的枚举,你的标准枚举。

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

    AddUser = 2,

    EditUser = 3,

    DeleteUser = 4
}

接下来,我有我的 Permission 类。

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

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

如您所见,我有一个 ID 和一个名称,然后是一个将 Id 转换为我的 PermissionCode 枚举的属性。

映射如下所示:

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

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

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

由于 PermissionCode 属性是派生的,我们在映射中不做任何事情。

映射后的我的表结构如下所示:

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

    CONSTRAINT PK_Permissions PRIMARY KEY CLUSTERED (PermissionId)
)

如果您想使用名称而不是整数值,您可以稍作修改。这取决于您的个人喜好。

【讨论】:

    【解决方案3】:

    这是对我有用的方法

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

    在这里查看更多信息answer

    【讨论】:

    • 感谢您的帖子。我试试看!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多