2009-05-23 5 views
3

J'ai une table appelée UserPermissions avec un FK dans la table users par userId, puis une colonne de chaîne pour la valeur de chaîne d'une énumération.Mappage d'une liste d'énumérations

L'erreur que je vois est NHibernate.MappingException: Une association de la table UserPermissions fait référence à une classe unmapped: GotRoleplay.Core.Domain.Model.Permission

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

la propriété dans ma classe User:

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

ma table de base de données:

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

Ma tentative de cartographier la propriété des autorisations de mon objet utilisateur:

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

Qu'est-ce que je fais mal qu'il ne peut pas mapper l'autorisation à une liste de valeurs ENUM?

+0

Ainsi, après beaucoup de bricoler, je fini par avoir à créer un nouvel objet appelé UserPermission et la carte à la table UserPermissions avec une propriété Permission en utilisant mon enum comme type de données. Cela fonctionne très bien, mais des autorisations peuvent être attachées aux rôles et aux utilisateurs, ce qui signifie que ma requête sélectionnée pour obtenir TOUTES les permissions assignées à un utilisateur (y compris tous leurs rôles) nécessite un ensemble compliqué d'instructions linq. Je préférerais ne pas faire ça. Quelqu'un a des idées? – Josh

Répondre

1

Je pensais que je posterais le code que j'ai choisi pour ma solution. C'est seulement une solution de contournement. Je souhaite que Fluent supporte les listes Enum, mais jusqu'à ce qu'il le fasse, voici une solution possible:

L'Enum - Ceci est mon enum, votre énumération standard.

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

    AddUser = 2, 

    EditUser = 3, 

    DeleteUser = 4 
} 

Ensuite, j'ai ma classe d'autorisation.

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

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

Comme vous pouvez le voir, j'ai un identifiant et un nom, puis une propriété qui convertit le Id dans mon PermissionCode ENUM.

La cartographie ressemble à ceci:

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

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

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

Puisque la propriété PermissionCode est dérivé, nous ne faisons rien dans la cartographie.

Ma structure de table derrière la cartographie ressemble à ceci:

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

    CONSTRAINT PK_Permissions PRIMARY KEY CLUSTERED (PermissionId) 
) 

Si vous voulez utiliser le nom au lieu de la valeur entière, avec quelques légères modifications que vous pouvez. Cela dépend de vos préférences personnelles.

1

Vous devez spécifier le type afin que NHibernate puisse convertir la valeur de la table en un membre de l'enum d'autorisation.

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

Edité ajouter: Je suis désolé, je aurais dû remarqué que vous aviez ce que ManyToMany. Ce n'est pas possible: Vous ne pouvez pas avoir une collection Users (l'autre côté de m: m) suspendue une énumération. Vous devez définir ceci comme 1: m ou créer une table d'autorisation et classer et mapper comme m: m.

+0

J'ai essayé d'utiliser votre suggestion et CustomTypeIs n'existe pas en tant qu'option valide. J'ai essayé à la place d'utiliser .CollectionType (typeof (Permission)) mais je vois toujours la même erreur: Une association de la table UserPermissions fait référence à une classe non mappée: GotRoleplay.Core.Domain.Model.Permission – Josh

3

ici le chemin qui a fonctionné pour moi

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

regarder ici pour plus d'informations answer

+0

Merci pour votre message. Je vais essayer! – Josh