Free one-to-many NHibernate matching

I have the following 2 classes:

Advertising

public virtual int Id { get; set; public virtual IList<AdvertImage> AdvertImages { get; set; } 

Advertising

 public virtual int Id { get; set; } public virtual string Filename { get; set; public virtual Advert Advert { get; set; } 

In the DB, my ad table has FK 'AdvertId', which refers to the Adverts table, which has a PK identifier.

This is a one-to-many mapping because a single ad can have many images.

My current NHibernate mappings (edited for brevity):

Advertising

 Id(x => x.Id) .GeneratedBy.Identity(); ... HasMany(x => x.AdvertImages) .KeyColumn("AdvertId") .Inverse(); ... Table("Adverts"); 

AdvertisingStore

 Id(x => x.Id) .GeneratedBy.Identity(); ... References(x => x.Advert) .Column("AdvertId"); ... Table("AdvertImages"); 

I create a new instance of Advert in the code, then populating the AdvertImages property with the List<AdvertImage> .

When I go over to save my Advert object in the database, I would like AdvertImages to be inserted into their AdvertImages table, but due to the relationship between the two tables, I first need the insertion of the advertisement to occur, so how is the PK identifier generated, which then can be inserted into the table AdvertImages. (When I create my AdvertImage list, I populate the Filename property, but obviously there is no new advertisement at this point, so I want it to be filled when the advertisement is saved in the database).

I tried experimenting with different Inverse () and Cascade settings, but so far have failed. Can anyone help?

+8
nhibernate fluent-nhibernate nhibernate-mapping fluent-nhibernate-mapping
source share
3 answers

You need to change the mapping of Advert to cascade:

 Id(x => x.Id) .GeneratedBy.Identity(); HasMany(x => x.AdvertImages) .KeyColumn("AdvertId") .Inverse() .Cascade.AllDeleteOrphan(); Table("Adverts"); 

You can then do something similar to save the Advert object, and then the AdvertImage children.

 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 objects usually contain add and remove methods for bidirectional relationships to each other:

 public class Advert { public virtual IList<AdvertImage> AdvertImages { get; set; } public virtual void AddImage(AdvertImage newImage) { newImage.Advert = this; AdvertImages.Add(newImage); } } 
+10
source share

I had the same problem. I spent some time trying to use various types of mapping. Then I found that my mappings were perfect, and in fact I needed to have a session in a transaction and use the Commit () method after the session.SaveOrUpdate () method.

 using(var session = sessionFactory.OpenSession()) using(var tx = session.BeginTransaction()) { // execute code that uses the session tx.Commit(); } 
+2
source share

Usually, for me, you usually need to set the foreign key column to allow zeros in the database - this will be your AdWordsId column, but I'm not sure if this will work in your case, since you are using an identifier. What NHibernate does is INSERT all with one query, and then updates the foreign key column of the child table with the correct parent table id. Perhaps this will work in your case.

Here are some similar questions that might help: Cascading one-to-many cascading with white NHibernate

+1
source share

All Articles