Reputation: 1452
i'm new to nhibernate so maybe the response depends on my lack of knowledge.
I created these two tables:
(sorry for italian language, i hope you can understand withouth any problems).
Then, i have these object in my model:
[Serializable]
public class Profilo
{
public virtual int Id { get; set; }
public virtual string Matricola { get; set; }
public virtual string Ruolo { get; set; }
public virtual IList ListaSedi { get; set; }
public Profilo()
{
ListaSedi = new List();
}
}
[Serializable]
public class Sede
{
public virtual string CodiceSede { get; set; }
public virtual string DescrizioneSede { get; set; }
public virtual Profilo Profilo { get; set; }
}
This is the way i mapped entities using fluent nhibernate:
public class Map_Sede : FluentNHibernate.Mapping.ClassMap
{
public Map_Sede()
{
Table("TBA_Sede");
Id(x => x.CodiceSede).Column("codice_sede").GeneratedBy.Assigned();
Map(x => x.DescrizioneSede)
.Column("descrizione");
References(prof => prof.Profilo)
.Column("codice_sede");
}
}
public class Map_Profilo : FluentNHibernate.Mapping.ClassMap
{
public Map_Profilo()
{
Table("TBA_Profilo");
Id(x => x.Id).Column("id").GeneratedBy.Identity();
Map(x => x.Matricola)
.Column("matricola");
Map(x => x.Ruolo)
.Column("ruolo");
HasMany(x => x.ListaSedi)
.AsBag()
.KeyColumns.Add("codice_sede")
.Not.LazyLoad()
.Cascade.None();
}
}
Now, i'd like to insert a new Profilo instance on my. Everything seems to work but nhibernate does not insert values on TBA_Profilo.codice_sede column. I noticed that the insert statement is composed by two parameters (matricola, ruolo) - why does it forget the third parameter?
I read somewhere (on nhibernate mailing list) that's quite normal 'cause nhiberate insert values with null first and then update the same records with right values contained in the list property.
Is it right? Am i doing any errors?
I hope to have clarified the situation. thx guys
ps: I'm using Nhibernate 2.1 and fluent nhibernate 1.1
UPDATE: This is the code i use to save entity.
var sesionFactory = NHibernateHelper.createSessionFactory();
using (NHibernate.ISession session = sesionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
try
{
session.SaveOrUpdate(entity);
transaction.Commit();
session.Flush();
}
catch (Exception)
{
transaction.Rollback();
throw;
}
finally
{
transaction.Dispose();
}
}
}
UPDATE 2: Following sly answer i slightly modified my solution. These are new model entities:
[Serializable]
public class Profilo
{
public virtual int Id { get; set; }
public virtual string Matricola { get; set; }
public virtual string Ruolo { get; set; }
public virtual IList ListaSedi { get; set; }
public Profilo()
{
ListaSedi = new List();
}
}
[Serializable]
public class Sede
{
public virtual string CodiceSede { get; set; }
public virtual string DescrizioneSede { get; set; }
public virtual IList ProfiliAssociati { get; set; }
}
And new mappings:
public class Map_Sede : FluentNHibernate.Mapping.ClassMap
{
public Map_Sede()
{
Table("TBA_Sede");
Id(x => x.CodiceSede).Column("codice_sede").GeneratedBy.Assigned();
Map(x => x.DescrizioneSede)
.Column("descrizione");
HasMany(x => x.ProfiliAssociati)
.AsBag()
.KeyColumns.Add("codice_sede")
.Cascade.All();
}
}
public class Map_Profilo : FluentNHibernate.Mapping.ClassMap
{
public Map_Profilo()
{
Table("TBA_Profilo");
Id(x => x.Id).Column("id").GeneratedBy.Identity();
Map(x => x.Matricola)
.Column("matricola");
Map(x => x.Ruolo)
.Column("ruolo");
HasMany(x => x.ListaSedi)
.AsBag()
.Inverse()
.KeyColumns.Add("codice_sede")
.Cascade.SaveUpdate();
}
}
Now it seems quite to work: i mean that nhibernate can write TBA_Profilo.codice_sede column even if it doesn't cicle on Profilo.IList (it inserts the last element of this List).
Any ideas?
Upvotes: 0
Views: 3013
Reputation: 9351
Your mapping is wrong, try this:
public class Map_Profilo : FluentNHibernate.Mapping.ClassMap
{
public Map_Profilo()
{
Table("TBA_Profilo");
Id(x => x.Id).Column("id").GeneratedBy.Identity();
Map(x => x.Matricola)
.Column("matricola");
Map(x => x.Ruolo)
.Column("ruolo");
HasMany(x => x.ListaSedi)
.AsBag()
.KeyColumns.Add("codice_sede")
.Not.LazyLoad()
.Cascade.SaveUpdate();
}
}
public class Map_Sede : FluentNHibernate.Mapping.ClassMap
{
public Map_Sede()
{
Table("TBA_Sede");
Id(x => x.CodiceSede).Column("codice_sede").GeneratedBy.Assigned();
Map(x => x.DescrizioneSede)
.Column("descrizione");
References(prof => prof.Profilo)
.Column("codice_sede")
.Cascade.None()
.Inverse();
}
}
The key is, you need the parent profilio to save its child items. Have the child items do nothing to its parent. Also, your table diagram looks wrong, profolio should not have a key to sede, but sede should have a fk to profolio.
Upvotes: 0
Reputation: 15217
KeyColumns mapping is applied only child table in many-to-one connection.
If you want to have connection you will need to use Id column from TBA_portfolio
table and reference it from TBA_Sede
.
Something like this:
Tba_portfolio Id|matricola|ruolo
Tba_sede Id|PorfolioId|descrizione
Upvotes: 1