Fluent NHibernate One-To-Many Mapping
fluent-nhibernate, fluent-nhibernate-mapping, nhibernate, nhibernate-mapping
Solution
You need to change your `Advert` mapping to cascade:
Id(x => x.Id)
.GeneratedBy.Identity();
HasMany(x => x.AdvertImages)
.KeyColumn("AdvertId")
.Inverse()
.Cascade.AllDeleteOrphan();
Table("Adverts");
You should then be able to do something like this to persist an `Advert` object and it's children `AdvertImage`.
Advert newAdvert = new Advert();
AdvertImage newImage = new AdvertImage();
newImage.Advert = newAdvert;
newAdvert.AdvertImages.Add(newImage);
using(NHibernate.ISession session = SessionFactory.GetCurrentSession())
{
using (NHibernate.ITransaction tran = session.BeginTransaction())
{
session.Save(newAdvert);
tran.Commit();
}
}
My entities usually contain Add and Remove methods for bidirectional one to many relationships like this:
public class Advert
{
public virtual IList<AdvertImage> AdvertImages { get; set; }
public virtual void AddImage(AdvertImage newImage)
{
newImage.Advert = this;
AdvertImages.Add(newImage);
}
}
Problem
I have the following 2 classes: Advert ``` public virtual int Id { get; set; public virtual IList<AdvertImage> AdvertImages { get; set; } ``` AdvertImage ``` public virtual int Id { get; set; } public virtual string Filename { get; set; public virtual Advert Advert { get; set; } ``` In the DB, my AdvertImages table has the FK 'AdvertId' which relates to the Adverts table which has the PK of 'Id'. This is a One-To-Many mapping, in that one advert can have many images. My Fluent NHibernate mappings (edited for brevity) are: AdvertMap ``` Id(x => x.Id) .GeneratedBy.Identity(); ... HasMany(x => x.AdvertImages) .KeyColumn("AdvertId") .Inverse(); ... Table("Adverts"); ``` AdvertImageMap ``` Id(x => x.Id) .GeneratedBy.Identity(); ... References(x => x.Advert) .Column("AdvertId"); ... Table("AdvertImages"); ``` I am creating a new instance of `Advert` in code, then populating the `AdvertImages` property (of Advert) with a `List<AdvertImage>`. When I go to persist my `Advert` object to the DB, I would like the AdvertImages to be inserted into their AdvertImages table, but due to the relationship between the 2 tables, I need the Advert insertion to happen first, so as the PK Id is generated, which can then be inserted in the AdvertImages table. (When I create my list of AdvertImage, I am populating the Filename property, but obviously don't have the new AdvertId at that stage, so want that to be populated when the advert is persisted to the DB). I have tried experimenting with different Inverse() and Cascade settings but haven't succeeded yet. Can anyone help please?