I've tried to reproduce your scenario like this: a Client (object A) having more Agreemnts (object B) referencing many Debtors (object C). I will use <bag>
and IList<>
but the same works for <set>
public class Client
{
public virtual int ID { get; set; }
public virtual IList<Agreement> Agreements { get; set; }
...
}
public class Agreement
{
public virtual int ID { get; set; }
public virtual Client Client { get; set; }
public virtual IList<Debtor> Debtors { get; set; }
...
}
public class Debtor
{
public virtual int ID { get; set; }
public virtual IList<Agreement> Agreements { get; set; }
...
}
Now the simplified class mapping, but complete <bag>
mapping
Client:
<class name="Client" table="[dbo].[Client]" lazy="true" >
<id name="ID" column="[ClientId]" generator="native" />
...
<bag name="Agreements" inverse="true" cascade="all" >
<key column="AgreementId"></key>
<one-to-many class="Agreement"/>
</bag>
Agreement:
<class name="Agreement" table="[dbo].[Agreement]" lazy="true" >
<id name="ID" column="[AgreementId]" generator="native" />
<many-to-one name="Client" column="ClientId" />
<bag name="Debtors"
table="[dbo].[AgreementDebtor]"
inverse="false" cascade="all" >
<key column="AgreementId"></key>
<many-to-many class="Debtor" column="DebtorId" />
</bag>
Debtor:
<class name="Debtor" table="[dbo].[Debtor]" lazy="true" >
<id name="ID" column="[DebtorId]" generator="native" />
<bag name="Agreements"
table="[dbo].[AgreementDebtor]"
inverse="true" cascade="all" >
<key column="DebtorId"></key>
<many-to-many class="Agreement" column="AgreementId" />
</bag>
Having this mapping, we can call this:
var client = new Client();
var debtor = new Debtor();
var agreement = new Agreement();
agreement.Client = client;
client.Agreements.Add(agreement);
agreement.Debtors.Add(debtor);
debtor.Agreements.Add(agreement);
session.Save(client);
session.Flush();
the Inserts issued and cought by profiler:
RPC:Completed exec sp_executesql N'INSERT INTO [dbo].[Client] ...
RPC:Completed exec sp_executesql N'INSERT INTO [dbo].[Agreement] ...
RPC:Completed exec sp_executesql N'INSERT INTO [dbo].[Debtor] ...
RPC:Completed exec sp_executesql N'INSERT INTO [dbo].[AgreementDebtor] (AgreementId, DebtorId) VALUES ...
This way, with only one call to "Insert" the Client instance... all other sutff is triggered in a cascade, it should work