使用未映射列映射组合键 [英] Map composite key with unmapped column

查看:168
本文介绍了使用未映射列映射组合键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何映射组合键,如果它的一部分没有映射到我的实体中?



示例:

我有一个包含列的表 ITEMDELIVERY


  • (PK)
  • DELIVERY_DATE b


我有一个包含列的表 ITEMDELIVERYDETAIL

ITEMDELIVERY_ID
(PK)

  • ITEMDELIVERY_ID
  • PARTITIONDATE (PK,FK)


    正如你所看到的,两个表中都有一个复合键, ITEMDELIVERYDETAIL 有一个复合外键给 ITEMDELIVERY



    在我的域模型 ItemDeliveryDetail 中不存在属性PartitionDate,映射到列 PARTITIONDATE (请参阅此处

    但现在,我如何映射组合键 ITEMDELIVERYDETAIL



    我尝试了以下操作,
    $ b

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

    我得到以下错误:


    NHibernate.PropertyNotFoundException:未能找到类属性 'DeliveryDate' 的吸气剂 'REM.Domain.NHibernate.ItemDeliveryDetail'







    更新:



    我想我找到了解决方案:


    1. ItemDeliveryDetail 的映射中删除对 ItemDelivery code>: mapping.References(x => x.ItemDelivery);. Columns(ITEMDELIVERY_ID,PARTITIONDATE);

    2. 更改组合键的声明为:

        mapping.CompositeId()。KeyProperty x => x.Id,ITEMDELIVERYDETAIL_ID)
      .KeyReference(x => x.ItemDelivery,ITEMDELIVERY_ID,
      PARTITIONDATE);


    这有副作用, code> ItemDeliveryDetail 不能级联保存 ItemDelivery 。它需要预先保存。

    然而,我想知道一件事情:

    这会创建一个三列PK吗?如果是这样,如何避免它,只需要创建一个两列所需的PK?

    解决方案

    你有一个传统的数据库,并将永远不会生成与SchemaExport,所以没关系,如果NH认为它有3个PK列或1。



    在看你的问题带顺序的复合键,如果你的ID是独一无二的,那么它会更好

      mapping.Id(x => x.Id).GeneratedBy.SequenceIdentity(SQ_TRANSFORM_ITEMDEL_IDDID); 
    mapping.Reference(x => x.ItemDelivery).Columns(ITEMDELIVERY_ID,PARTITIONDATE);

    即使在db中,PK跨越两列

    更新:您的发票示例中的棘手问题。在连接中有第二列(作为查询优化器应该添加到连接的地方)的一种方法。

      HasManyToMany(U => u.ItemDeliveryDetails)
    。表( INVOICEITEM_IDD)
    .ChildWhere( PARTITIONDATE = nhGeneratedAliasForINVOICEITEM_IDD.PARTITIONDATE);


    How do I map a composite key, if part of it is not mapped in my entity?

    Example:

    I have a table ITEMDELIVERY containing the columns:

    • ITEMDELIVERY_ID (PK)
    • DELIVERY_DATE (PK)

    I have a table ITEMDELIVERYDETAIL containing the columns:

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

    As you can see, there is a composite key in both tables and ITEMDELIVERYDETAIL has a "composite" foreign key to ITEMDELIVERY.

    There exists no property PartitionDate in my domain model ItemDeliveryDetail that could be mapped to the column PARTITIONDATE (see here and here for the reasons).

    But now, how do I map the composite key in ITEMDELIVERYDETAIL?

    I tried the following, but that doesn't work:

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

    I get the following error:

    NHibernate.PropertyNotFoundException: Could not find a getter for property 'DeliveryDate' in class 'REM.Domain.NHibernate.ItemDeliveryDetail'


    UPDATE:

    I think I found the solution:

    1. Remove the reference to ItemDelivery from the mapping of ItemDeliveryDetail: mapping.References(x => x.ItemDelivery);.Columns("ITEMDELIVERY_ID", "PARTITIONDATE");
    2. Change the declaration of the composite key to this:

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

    This has the side effect that saving an ItemDeliveryDetail can't cascade save an ItemDelivery. It needs to be saved upfront.

    However, I wonder about one thing:
    Will this create a PK with three columns? If so, how to avoid it and only create a PK for the two columns needed?

    解决方案

    it looks like you have a legacy db and will never generate it with SchemaExport, so it doesnt matter if NH thinks it has 3 PK columns or 1.

    after looking at your question Composite key with sequence and if your Id is unique alone then it would be better to

    mapping.Id(x => x.Id).GeneratedBy.SequenceIdentity("SQ_TRANSFORM_ITEMDEL_IDDID");
    mapping.Reference(x => x.ItemDelivery).Columns("ITEMDELIVERY_ID", "PARTITIONDATE");
    

    even if in the db the PK spans both columns

    Update: tricky thing in your example of Invoice. There is a hack to have the second column in the join (as a where which the query optimizer should add to the join)

    HasManyToMany(u => u.ItemDeliveryDetails)
        .Table("INVOICEITEM_IDD")
        .ChildWhere("PARTITIONDATE = nhGeneratedAliasForINVOICEITEM_IDD.PARTITIONDATE");
    

    这篇关于使用未映射列映射组合键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆