Fluent NHibernate many-to-many relationship on existing database

Declan Dowling picture Declan Dowling · Sep 12, 2013 · Viewed 7.7k times · Source

I am mapping an existing database using Fluent NHibernate and have encountered a problem when trying to populate many-to-many collections. The database itself is not set up correctly using foreign keys, here is a simplified example of the problem I'm having.

Tables:

  1. Users
  2. Groups
  3. UsersInGroups

Entity Classes:

public class User
{
    public virtual long UserID { get; set; }
    public virtual string Name { get; set; }

    public virtual IList<Group> Groups { get; set; }
}

public class Group
{
    public virtual long GroupID { get; set; }
    public virtual string Name { get; set; }

    public virtual IList<User> Users { get; set; }
}

public class UserInGroup
{
    public virtual User User { get; set; }
    public virtual Group Group { get; set; }

    #region Fluent NHibernate Composite Key Overrides

    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;

        var compare = obj as UserInGroup;

        if (compare == null)
            return false;

        return User.UserID == compare.User.UserID &&
               Group.GroupID == compare.Group.GroupID;
    }

    public override int GetHashCode()
    {
        return (User.UserID + "|" + Group.GroupID).GetHashCode();
    }

    #endregion
}

Mapping Classes:

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        Table("Users");
        Id(x => x.UserID, "UserID").GeneratedBy.Identity();

        Map(x => x.Name, "Name");

        HasManyToMany(x => x.Groups).Table("UsersInGroups")
                                    .ParentKeyColumn("GroupID")
                                    .ChildKeyColumn("UserID")
                                    .Cascade.All();
    }
}

public class GroupMap : ClassMap<Group>
{
    public GroupMap()
    {
        Table("Groups");
        Id(x => x.GroupID, "GroupID").GeneratedBy.Identity();

        Map(x => x.Name, "Name");

        HasManyToMany(x => x.Users).Table("UsersInGroups")
                                   .ParentKeyColumn("UserID")
                                   .ChildKeyColumn("GroupID")
                                   .Inverse();
    }
}

public class UserInGroupMap : ClassMap<UserInGroup>
{
    public UserInGroupMap()
    {
        Table("UsersInGroups");

        CompositeId().KeyReference(x => x.User, "UserID")
                     .KeyReference(x => x.Group, "GroupID");
    }
}

In my configuration I have eager loading enabled, the HasMany relationships seem to be working okay but the HasManyToMany relationships are returning an empty collection. I have tried a few different combinations of Cascade.All() and Inverse on the collections all with no success. Any help would be much appreciated, thanks.

Answer

Marcos picture Marcos · May 12, 2015
HasManyToMany(x => x.Users).Table("UsersInGroups")
                           .ParentKeyColumn("UserID")
                           .ChildKeyColumn("GroupID")
                           .Not.LazyLoad();