使用未映射的列映射复合键

时间:2011-12-13 16:32:04

标签: c# nhibernate fluent-nhibernate

如果复合键的一部分未映射到我的实体中,如何映射复合键?

示例:

我有一个包含列的表ITEMDELIVERY

  • ITEMDELIVERY_ID(PK)
  • DELIVERY_DATE(PK)

我有一个包含列的表ITEMDELIVERYDETAIL

  • ITEMDELIVERYDETAIL_ID(PK)
  • ITEMDELIVERY_ID(FK)
  • PARTITIONDATE(PK,FK)

如您所见,两个表中都有一个复合键,而ITEMDELIVERYDETAIL具有ITEMDELIVERY的“复合”外键。

我的域模型ItemDeliveryDetail中没有可以映射到列PARTITIONDATE的属性PartitionDate(原因请参阅herehere)。

但是现在,如何在ITEMDELIVERYDETAIL中映射复合键?

我尝试了以下操作,但这不起作用:

mapping.CompositeId().KeyProperty(x => x.Id, "ITEMDELIVERYDETAIL_ID")
                     .KeyProperty(x => x.ItemDelivery.DeliveryDate,
                                       "PARTITIONDATE");

我收到以下错误:

  

NHibernate.PropertyNotFoundException:找不到类'REM.Domain.NHibernate.ItemDeliveryDetail'中属性'DeliveryDate'的getter


更新:

我想我找到了解决方案:

  1. ItemDeliveryItemDeliveryDetail
  2. 的映射中删除对mapping.References(x => x.ItemDelivery);.Columns("ITEMDELIVERY_ID", "PARTITIONDATE");的引用
  3. 将复合键的声明更改为:

    mapping.CompositeId().KeyProperty(x => x.Id, "ITEMDELIVERYDETAIL_ID")
                         .KeyReference(x => x.ItemDelivery, "ITEMDELIVERY_ID",
                                                            "PARTITIONDATE");
    
  4. 这样做的副作用是保存ItemDeliveryDetail无法级联保存ItemDelivery。它需要预先保存。

    然而,我想知道一件事:
    这会创建一个包含三列的PK吗?如果是这样,如何避免它,只为所需的两列创建PK?

1 个答案:

答案 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");