You don't need to map your join table with its own type. And also, you shouldn't expose Formula.ID from a property of another class. Here is what you need
3 database Tables
Ingredients: PK:ID(Identity(1,1), Name, Description
Formula: PK:ID(Identity(1,1), Name, Description
IngredientFormulaJoin: FK:IngredientID, FK:FormulaID
create table dbo.Ingredients(id int primary key identity(1,1), Name varchar(100))
create table dbo.formulas(id int primary key identity(1,1), Name varchar(100))
create table dbo.ingredientformulajoin(ingredientid int foreign key references dbo.ingredients(id), formulaid int foreign key refernces dbo.formula(id))
public class Forumula() {
public Formula(){
Ingredients = new List<Ingredient>();
}
public int PK:ID(Identity(1,1) { get; set; }
public IList<Ingredient> Ingredients{ get; set; }
}
public class Ingredient() {
public Ingredient(){
Formulas = new List<Formula>
}
public int ID { get; set; }
public IList<Forumula> Formulas { get; set; }
}
Here is the mapping:
<class name="App.Core.Domain.Ingredient, App.Core" table="ingredients">
<set name="Formulas" table="formulaingredientjoin" inverse="false" cascade="all">
<key column="ingredientid"/>
<many-to-many class="App.Core.Domain.Forumula, App.Core" column="formulaid"/>
</set>
</class>
<class name="App.Core.Domain.Formula, App.Core" table="formulas">
<set name="Ingredients" table="formulaingredientjoin" inverse="false" cascade="all">
<key column="formulaid"/>
<many-to-many class="App.Core.Domain.Ingredient, App.Core" column="ingredientid"/>
</set>
</class>
Add to the collections like this:
Formula formula = new Formula();
formula.Ingredients.Add(ingredient1)
formula.Ingredients.Add(ingredient2)
formula.Ingredients.Add(ingredient3)
session.Save(formula);
session.Flush();
Ingredient ingredient = new Ingredient();
ingredeient.Formulas.Add(formula1);
ingredeient.Formulas.Add(formula2);
session.Save(ingredient);
session.Flush();
You should never need to Map a join table as its own class. Also allow classes to encapsulate their own types. The only thing that should return a formula ID is a formula. You wouldn't put 'FormulaID' in ingredients for example, rather, call formula.ID.