オブジェクトをデータベースに永続化しようとしています。この操作は2つのテーブルに触れる必要があります。
[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");
}
}
これは私のマッピングです:
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());
}
}
これはnhibernateによって使用されるSQLです:
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 */)
sqlステートメントのReportIdは、コントローラーアクションで設定していないため、C#のデフォルト(GUID)です。NHibernateはレポートテーブルのIDを生成します。コントローラアクションでIDを設定したとき
report.Id = Guid.NewGuid();
SQLはパラメータとして異なるIDを使用します。
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 */)
NHibernateによって生成されたIDを2番目のテーブルに使用するにはどうすればよいですか?
アップデート:
ManyToOneパーツを明示的にマッピングしようとしました
this.ManyToOne(x => x.Report, mapper => mapper.Column("ReportId"));
しかし、これでは、レポート位置に挿入しようとさえしません。
代わりに私がこのようなことをするとき
this.ManyToOne(x => x.Report, mapper => mapper.Column("foo"));
このSQLステートメントを作成します
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 */)
これで、fooは正しいキーを持ちます。誰かがこの振る舞いを説明し、解決策を提供してもらえますか?