如果复合键的一部分未映射到我的实体中,如何映射复合键?
示例:
我有一个包含列的表ITEMDELIVERY
:
ITEMDELIVERY_ID
(PK)DELIVERY_DATE
(PK)我有一个包含列的表ITEMDELIVERYDETAIL
:
ITEMDELIVERYDETAIL_ID
(PK)ITEMDELIVERY_ID
(FK)PARTITIONDATE
(PK,FK)如您所见,两个表中都有一个复合键,而ITEMDELIVERYDETAIL
具有ITEMDELIVERY
的“复合”外键。
我的域模型ItemDeliveryDetail
中没有可以映射到列PARTITIONDATE
的属性PartitionDate(原因请参阅here和here)。
但是现在,如何在ITEMDELIVERYDETAIL
中映射复合键?
我尝试了以下操作,但这不起作用:
mapping.CompositeId().KeyProperty(x => x.Id, "ITEMDELIVERYDETAIL_ID")
.KeyProperty(x => x.ItemDelivery.DeliveryDate,
"PARTITIONDATE");
我收到以下错误:
NHibernate.PropertyNotFoundException:找不到类'REM.Domain.NHibernate.ItemDeliveryDetail'中属性'DeliveryDate'的getter
更新:
我想我找到了解决方案:
ItemDelivery
:ItemDeliveryDetail
mapping.References(x => x.ItemDelivery);.Columns("ITEMDELIVERY_ID", "PARTITIONDATE");
的引用
将复合键的声明更改为:
mapping.CompositeId().KeyProperty(x => x.Id, "ITEMDELIVERYDETAIL_ID")
.KeyReference(x => x.ItemDelivery, "ITEMDELIVERY_ID",
"PARTITIONDATE");
这样做的副作用是保存ItemDeliveryDetail
无法级联保存ItemDelivery
。它需要预先保存。
然而,我想知道一件事:
这会创建一个包含三列的PK吗?如果是这样,如何避免它,只为所需的两列创建PK?
答案 0 :(得分:1)
看起来你有一个遗留数据库并且永远不会使用SchemaExport生成它,所以如果NH认为它有3个PK列或1个就无所谓。
在查看您的问题Composite key with sequence之后,如果您的ID是唯一的,那么
会更好mapping.Id(x => x.Id).GeneratedBy.SequenceIdentity("SQ_TRANSFORM_ITEMDEL_IDDID");
mapping.Reference(x => x.ItemDelivery).Columns("ITEMDELIVERY_ID", "PARTITIONDATE");
即使在数据库中,PK跨越两列
更新:在你的发票示例中有点棘手的事情。有一个hack在连接中有第二列(作为查询优化器应该添加到连接的位置)
HasManyToMany(u => u.ItemDeliveryDetails)
.Table("INVOICEITEM_IDD")
.ChildWhere("PARTITIONDATE = nhGeneratedAliasForINVOICEITEM_IDD.PARTITIONDATE");