Getting ManyToMany relationship to load

2019-09-16 08:09发布

I have User object with a list of groups that it belongs to:

public UserHeaderMap()
{
    Table("USER_HEADER");
    Id(x => x.Id, "USER_ID");

    HasManyToMany(x => x.Groups)
        .Table("USER_GROUP_COMPOSITE")
        .ParentKeyColumn("USER_ID")
        .ChildKeyColumn("GROUP_ID")
        .Cascade.SaveUpdate()
        .Inverse();
}

How do I need to modify my mapping or the way I'm retrieving my user object to fill the Groups list upon retrieval? I'm sure there are different options here but I'm not sure which is the best. The collection is currently null whenever I retrieve a User object from the database. I retrieve it using this:

UserHeader userFound = session.Load<UserHeader>(newUser.Id);

Edit:

public class UserHeader
{
    public virtual Guid Id { get; set; }
    public virtual IList<GroupHeader> Groups { get; set; }

    public UserHeader(IList<GroupHeader> groups)
    {
        Groups = groups;
    }

    public UserHeader()
    {
        Groups = new List<GroupHeader>();
    }

    public override bool Equals(object obj)
    {
        bool retVal = false;
        if (obj is UserHeader)
        {
            UserHeader otherUser = (UserHeader)obj;

            if (Id == otherUser.Id)
                retVal = true;
        }

        return retVal;
    }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }
}

Edit2: This is the way I was originally querying the data. It's grabbing everything except the many to many relationship.

UserHeader userFound = session.CreateCriteria<UserHeader>()
                              .Add(Example.Create(newUser))
                              .UniqueResult<UserHeader>();

Edit3: Unit test The following unit test fails on foreach (GroupHeader group in userFound.Groups). I can clearly see from the SQL that it is creating the relationship between User and Group in the SQL output. I can post it if necessary.

[TestMethod]
public void CanAddUserToGroup()
{
    using (NHibernate.ISession session = SessionOrigin.Current.GetSession())
    {
        using (NHibernate.ITransaction tran = session.BeginTransaction())
        {
            session.SaveOrUpdate(newUser);
            session.SaveOrUpdate(newGroup);
            tran.Commit();
        }

        newGroup.AddUser(newUser);
        using (NHibernate.ITransaction tran = session.BeginTransaction())
        {
            session.SaveOrUpdate(newGroup);
            tran.Commit();
        }

        GroupHeader groupFound = session.CreateCriteria<GroupHeader>()
            .Add(Example.Create(newGroup))
            .UniqueResult<GroupHeader>();

        UserHeader userFound = session.CreateCriteria<UserHeader>()
            .Add(Example.Create(newUser))
            .UniqueResult<UserHeader>();

        UserHeader userFound2 = session.Load<UserHeader>(newUser.Id);

        Assert.IsNotNull(groupFound, "Failed to find group after insertion");
        Assert.IsNotNull(userFound, "Failed to find user after insertion");

        UserHeader userInGroup = null;
        GroupHeader groupInUser = null;

        foreach (UserHeader user in groupFound.Users)
        {
            if (user.Equals(newUser))
                userInGroup = user;
        }

        foreach (GroupHeader group in userFound.Groups)
        {
            if (group.Equals(newGroup))
                groupInUser = group;
        }

        Assert.IsNotNull(userInGroup, "Failed to add a new user to group");
        Assert.IsNotNull(groupInUser, "Failed to add a new group to a user");

        using (NHibernate.ITransaction tran = session.BeginTransaction())
        {
            session.Delete(newUser);
            session.Delete(newGroup);
            tran.Commit();
        }
    }
}

1条回答
Melony?
2楼-- · 2019-09-16 09:11

Your unit test code is not correct.

Since both the group and the user are already loaded in the session, the criteria queries return the same instances.

If the collections were null in memory, they'll still be null after the query. Also, you're adding to just one side of a bidirectional association.

Last but not least, you are testing too many unrelated things in the same test method.

查看更多
登录 后发表回答