I am trying to persist an object into the database. This operation should touch two tables.
[HttpPost]
public ActionResult Create(Report report)
{
try
{
report.Positions = new Iesi.Collections.Generic.HashedSet<Position>();
var desks = this.session.Query<Desk>().ToList();
foreach (var desk in desks)
{
foreach (var comm in desk.Commodities)
{
report.Positions.Add(
new Position
{
Report = report,
ReportId = report.Id,
Desk = desk,
DeskId = desk.Id,
Commodity = comm,
CommodityId = comm.Id,
Value = .0
});
}
}
this.session.Save(report);
return this.RedirectToAction("Index");
}
catch
{
// some handling
return this.RedirectToAction("Index");
}
}
This is my mapping:
public class EntityMapping<TKey, TEntity> : ClassMapping<TEntity>
where TEntity : Entity<TKey>
{
public EntityMapping()
{
this.Id(x => x.Id, mapper => mapper.Generator(Generators.GuidComb));
}
}
public class PositionMapping : ClassMapping<Position>
{
public PositionMapping()
{
this.Table("REPORTPOSITIONS");
this.ComposedId(
x =>
{
x.Property(p => p.ReportId);
x.Property(p => p.DeskId);
x.Property(p => p.CommodityId);
});
this.Version(x => x.Version, mapper => mapper.Generated(VersionGeneration.Always));
this.Property(x => x.Value, mapper => mapper.Column("Position"));
}
}
public class ReportMapping : EntityMapping<Guid, Report>
{
public ReportMapping()
{
this.Table("REPORTS");
this.Property(x => x.ReportDate, mapper => mapper.Type(NHibernateUtil.Date));
this.Set(
x => x.Positions,
mapper =>
{
mapper.Key(km => km.Column("ReportId"));
mapper.Lazy(CollectionLazy.Lazy);
mapper.Inverse(true);
mapper.Cascade(Cascade.All | Cascade.DeleteOrphans);
},
rel => rel.OneToMany());
}
}
and this is the sql used by nhibernate:
INSERT INTO REPORTS
(ReportDate,
Id)
VALUES ('2012-06-11T00:00:00.00' /* @p0_0 */,
'7f4d8f3d-1175-4713-bd1c-a06d00bfc614' /* @p1_0 */)
INSERT INTO REPORTPOSITIONS
(Position,
CommodityId,
DeskId,
ReportId)
VALUES (0 /* @p0_0 */,
'3a7d80c4-85e9-ba4b-80d2-064f7f0b58b5' /* @p1_0 */,
'ed7c4e75-7417-a241-a40a-0ff4bfad7172' /* @p2_0 */,
'00000000-0000-0000-0000-000000000000' /* @p3_0 */)
The ReportId in the sql statement is C#'s default(GUID), because i have not set it in the controller action. NHibernate generates the id for the reports table. When I set the Id in the controller action
report.Id = Guid.NewGuid();
the sql uses different ids as parameters:
INSERT INTO REPORTS
(ReportDate,
Id)
VALUES ('2012-06-11T00:00:00.00' /* @p0_0 */,
'6164264e-29cd-4d9c-befd-a06d00c2defd' /* @p1_0 */)
INSERT INTO REPORTPOSITIONS
(Position,
CommodityId,
DeskId,
ReportId)
VALUES (0 /* @p0_0 */,
'3a7d80c4-85e9-ba4b-80d2-064f7f0b58b5' /* @p1_0 */,
'ed7c4e75-7417-a241-a40a-0ff4bfad7172' /* @p2_0 */,
'594b2206-7c25-4430-af18-5f2643f6c7bf' /* @p3_0 */)
How do I use the id generated by NHibernate for the second table?
UPDATE:
I tried to map the ManyToOne part explicitly
this.ManyToOne(x => x.Report, mapper => mapper.Column("ReportId"));
but with this it does not even try to insert into reportpositions;
When I instead do something like this
this.ManyToOne(x => x.Report, mapper => mapper.Column("foo"));
it creates this sql statement
INSERT INTO REPORTS
(ReportDate,
Id)
VALUES ('2012-06-11T00:00:00.00' /* @p0_0 */,
'4ff74d49-8749-400c-b079-a06d00e0bee5' /* @p1_0 */)
INSERT INTO REPORTPOSITIONS
(foo,
Position,
CommodityId,
DeskId,
ReportId)
VALUES ('4ff74d49-8749-400c-b079-a06d00e0bee5' /* @p0_0 */,
0 /* @p1_0 */,
'3a7d80c4-85e9-ba4b-80d2-064f7f0b58b5' /* @p2_0 */,
'ed7c4e75-7417-a241-a40a-0ff4bfad7172' /* @p3_0 */,
'00000000-0000-0000-0000-000000000000' /* @p4_0 */)
now foo has the correct key. Could someone please explain this behavior and offer a solution?