2009-05-23 16 views
3

Ich habe eine Tabelle namens UserPermissions mit einem FK in der Benutzer-Tabelle von userId und dann eine Zeichenfolge-Spalte für den String-Wert einer Aufzählung.Mapping einer Liste von Enums

Der Fehler, den ich sehen bin, ist NHibernate.MappingException: Ein Verein aus der Tabelle UserPermissions bezieht sich auf eine nicht zugeordnete Klasse: GotRoleplay.Core.Domain.Model.Permission

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

das Anwesen in meiner Benutzerklasse:

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

Meine Datenbanktabelle:

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

Mein Versuch, die Berechtigungen Eigentum meines Benutzerobjekt in Abbildung:

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

Was mache ich falsch, dass es nicht die Erlaubnis zu einer Liste von ENUM-Werte abbilden?

+0

So nach vieler Bastelei, ich ein neues Objekt namens Userpermission zu schaffen, die am Ende und wo es zu die UserPermissions-Tabelle mit einer Permission-Eigenschaft, die meine enum als den Datentyp verwendet. Dies funktioniert einwandfrei, aber Berechtigungen können Rollen und Benutzern zugeordnet werden, was bedeutet, dass meine SELECT-Abfrage, um JEDER Berechtigung, die einem Benutzer zugewiesen wird (einschließlich all ihrer Rollen), einen komplizierten Satz von Linq-Anweisungen erfordert. Ich würde das lieber nicht tun. Hat jemand Ideen? – Josh

Antwort

1

Ich dachte, ich würde den Code posten, den ich für meine Lösung gewählt habe. Es ist nur ein Workaround. Ich wünschte, Fluent würde Enum-Listen unterstützen, aber bis es funktioniert, hier ist eine mögliche Lösung:

Die Enum - Das ist meine Enum, Ihre Standard-Enum.

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

    AddUser = 2, 

    EditUser = 3, 

    DeleteUser = 4 
} 

Als nächstes habe ich meine Berechtigung Klasse.

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

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

Wie Sie sehen können, habe ich eine ID und einen Namen, und dann eine Eigenschaft, die die Id in meine PermissionCode Enum umwandelt.

Die Abbildung sieht wie folgt aus:

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

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

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

Da die PermissionCode Eigenschaft abgeleitet wird, wir tun nichts in der Abbildung.

Meine Tabellenstruktur hinter der Abbildung sieht wie folgt aus:

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

    CONSTRAINT PK_Permissions PRIMARY KEY CLUSTERED (PermissionId) 
) 

Wenn Sie den Namen anstelle der Integer-Wert, mit einigen geringfügigen Änderungen können Sie verwenden wollten. Es hängt von Ihren persönlichen Vorlieben ab.

1

Sie müssen den Typ angeben, damit NHibernate den Wert in der Tabelle in ein Mitglied der Permission-Enumeration konvertieren kann.

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

Edited hinzufügen: Es tut mir leid, sollte ich bemerkt haben, dass Sie dies als ManyToMany hatte. Das ist nicht möglich: Sie können keine Benutzer-Sammlung (andere Seite von m: m) an einer Aufzählung hängen lassen. Sie müssen dies als 1: m definieren oder eine Berechtigungstabelle und -klasse erstellen und diese als m: m zuordnen.

+0

Ich habe versucht, Ihren Vorschlag zu verwenden, und CustomTypeIs existiert nicht als gültige Option. Ich versuchte stattdessen mit .CollectionType (typeof (Permission)), aber ich sehe immer noch den gleichen Fehler: Eine Zuordnung aus der Tabelle UserPermissions bezieht sich auf eine nicht zugeordnete Klasse: GotRoleplay.Core.Domain.Model.Permission – Josh

3

hier ist die Art und Weise, die

für mich gearbeitet
HasMany(x => x.Licences) 
       .WithTableName("DriverLicence") 
       .AsElement("Level").AsBag(); 

Blick hier für weitere Informationen answer

+0

Vielen Dank für Ihren Beitrag. Ich werde es versuchen! – Josh

Verwandte Themen