0

I'm using NHibernate Conformist mappings. I've already creating some complex mappings using ManyToMany, OneToMany, Element, and Component relation types for my various collection properties. But I ran into one today that stumped me.

public class Permission
{
    public virtual long PermissionId { get; set; }
    public virtual string Name { get; set; }
}

public class User
{
    ...
    public virtual Set<string> Permissions { get; set; }
}

public class Group
{
    ...
    public virtual Set<string> Permissions { get; set; }
}

Table Permission has columns PermissionId and Name. Then there is table UserPermission with columns UserId and PermissionId and table GroupPermission with columns GroupId and PermissionId.

As you can see, Permission is an entity, and there is a many-to-many relationship between users-and-permissions and between groups-and-permissions. However, for purposes of ease of using the User and Group objects, I don't want User and Group to have a Set<Permission> (easily accomplished using the ManyToMany relation type in Conformist). I want to User and Group to have a set of permission names. Normally I'd achieve this with the Element relation type, except for the whole many-to-many-using-join-table problem.

How do I map a collection of simple types that are also many-to-many?

Nick Williams
  • 2,864
  • 5
  • 29
  • 43

1 Answers1

-1

If I understood you correctly, I would rather have the Permission class have the sets of User and Groups: (note the set, it is not of the System.Collections.Generic as nHibernate understands ISet to be Iesi.Collections.Generic.ISet<>

    public virtual Iesi.Collections.Generic.ISet<User> Users { get; set; }
    public virtual Iesi.Collections.Generic.ISet<Group> Groups { get; set; }

and in the mapping of Permission:

    <set name="Users" table="PermissionUser" lazy="true">
    <key column="PermissionId"/>
    <many-to-many class="User" column="UserId" />
    </set>

    <set name="Groups" table="PermissionGroup" lazy="true">
    <key column="PermissionId"/>
    <many-to-many class="Group" column="GroupId" />
    </set>

class User and Group will not have any set of Permissions.

MoB
  • 51
  • 8
  • This doesn't answer my question and doesn't help me any at all. I need the `User` class to gave a set of permission names so that, given a `User`, I can check whether they have a given permission in code. – Nick Williams Apr 01 '14 at 14:34
  • @NickWilliams: you certainly can check for permissions per User, this query does it: var query = session.QueryOver().JoinQueryOver(u => u.Users).Where(t => t.UserId == id); IList permissions = query.List(); so, apparently, you did not understand the mapping well, and thus thanks for the down vote!. That mapping does give you which user has what permission. – MoB Apr 02 '14 at 06:28
  • I understand the mapping just fine, it's just a bad design. The problem is there are only ~300 permissions, but there could be 300 MILLION or more users. The performance issues would be staggering with your approach. The vote down is because the answer did not actually answer my question: how to put a set of permission names in the user and group. – Nick Williams Apr 02 '14 at 15:03
  • @NickWilliams: my fault. I understand you now. I honestly did not SEE that you had set permissionName in your Group and User classes. I thought it was set, and thus was my answer of reversing the mapping. I do not think of any solution at the moment, but I am sure if you had the whole entity of permission (which you said you do not want) in the User and group classes, you would then be able to add IList PermissionNames { get { return Permissions.Select(x => x.PermissionName).ToList(); } }. Do not know if you can have it without referencing Permission in User – MoB Apr 03 '14 at 08:03
  • Yea. After several days of nothing working, I took a different approach. I just changed the database tables backing my model so that the join table uses the permission code instead of the permission ID. That way, I could use `Element` instead of `ManyToMany`. – Nick Williams Apr 04 '14 at 02:34