Reputation: 11597
My database has two tables:
Users
UserId PK
Likes
LikeId PK
LikedUserId FK
LikingUserId FK
These tables represent user 'likes'. Likes are directional - user A likes user B, but user B does not like user A.
I am mapping with NHibernate like this:
<class name="User" table="Users">
<id name="UserId">
<generator class="assigned"></generator>
</id>
<idbag name="LikedBy" table="Likes" inverse="true">
<collection-id column="LikeId" type="guid">
<generator class="guid.comb"/>
</collection-id>
<key column="LikedUserId"/>
<many-to-many column="LikingUserId" class="User"/>
</idbag>
<idbag name="Liking" table="Likes">
<collection-id column="LikeId" type="guid">
<generator class="guid.comb"/>
</collection-id>
<key column="LikingUserId"/>
<many-to-many column="LikedUserId" class="User"/>
</idbag>
</class>
Corresponding to this class:
public class User
{
public Guid UserId { get; set; }
public ICollection<User> LikedBy { get; set; }
public ICollection<User> Liking { get; set; }
}
This works fine. However, the Liking
and LikedBy
collections for two different users can get out of sync. For instance:
using (var session = new NHibHelp.OpenSession())
{
var user1 = session.GetById<User>(id1);
var user2 = session.GetById<User>(id2);
int initialCount = user2.LikedBy.Count();
user1.Liking.Add(user2);
session.Update(user1);
int finalCount = user2.LikedBy.Count();
Assert.AreEqual(initalCount,finalCount); // passes
}
So if I add to the Liking
collection of one user, the LikedBy
collection of another user is not updated. To have it updated, I need to do Session.Refresh()
.
This isn't ideal. I'm quite new to NHibernate, so I don't know if there is another solution - is there anything better I can do? For instance, is it possible to map this scenario in such a way that LikedBy
is automatically updated when appropriate?
Upvotes: 3
Views: 620
Reputation: 2433
You can add a method to the User
class that syncs both collections:
public class User
{
public Guid UserId { get; set; }
public ICollection<User> LikedBy { get; set; }
public ICollection<User> Liking { get; set; }
public void Like(User user)
{
this.Liking.Add(user);
user.LikedBy.Add(this);
}
}
You may also make this collections readonly to an external code:
private ICollection<User> likedBy;
private ICollection<User> liking;
public IEnumerable<User> LikedBy { get { return this.likedBy; } }
public IEnumerable<User> Liking { get { return this.liking; } }
<idbag access="field.camelcase" ... />
Upvotes: 2