tags:

views:

86

answers:

1

I have a Users table and a Networks table with a many-to-many relationship between them (a user may be long to multiple networks and a network may contain many users). The many-to-many relationship is held in a "UserNetworks" table that simply has two columns, UserId and NetworkId.

My classes look like this:

public class User
{
    public IList<Network> Networks {get; set;}
}

public class Network
{
    public IList<Usre> Users {get; set;}
}

The NHibernate mappings for these many-to-many collections looks like this:

User.hbm.xml:

<bag name="Networks" table="UserNetworks" cascade="save-update" inverse="true">
    <key column="UserId" />
    <many-to-many class="Network" column="NetworkId" />
</bag>

Network.hbm.xml:

<bag name="Users" table="UserNetworks" cascade="save-update">
    <key column="NetworkId" />
    <many-to-many class="User" column="UserId" />
</bag>

In my code, I create an association between a user and a network like so:

user.Networks.Add(network);
network.Users.Add(user);

I would expect the SQL run to simply perform one INSERT to the UserNetworks table. Instead, it executes a DELETE on the UserNetworks table with NetworkID = X, then proceeds to reinsert all the UserNetworks rows back in along with the new association.

What am I doing wrong?

+2  A: 

The behaviour is by design. See, NH do not know what's current/new/deleted in the list. So by deleting all and inserting whatever in the list will make sense.

o.k.w
Here's the text from the manual (section 15.5.1)..."Bags are the worst case. Since a bag permits duplicate element values and has no index column, no primary key may be defined. NHibernate has no way of distinguishing between duplicate rows. NHibernate resolves this problem by completely removing (in a single DELETE) and recreating the collection whenever it changes. This might be very inefficient."
Michael Gattuso
Perfect. I added an identity column to my UserNetworks table and switched to an IdBag and it worked just fine. Thanks!
Kevin Pang
Fantastic! That's what I did for my projects too. :)
o.k.w