流畅的NHibernate Child收集持久性问题

时间:2014-01-23 21:16:31

标签: nhibernate fluent-nhibernate

我有以下映射类(仅复制相关部分):

public class CardTemplateMapping : ClassMap<CardTemplate>
{
    public CardTemplateMapping()
    {
        Table("cardtemplate");

        Id(x => x.Id)
            .Column("id")
            .GeneratedBy.Native();

        HasMany(x => x.CostStructures)
            .KeyColumn("cardtemplate_id")
            .Cascade.All();

    }
}
public class CostStructureMapping : ClassMap<CostStructure>
{
    public CostStructureMapping()
    {
        Table("coststructure");

        Id(x => x.Id)
            .Column("id")
            .GeneratedBy.Native();

        References(x => x.CardTemplate)
            .Column("cardtemplate_id");

        HasMany(x => x.CostComponents)
            .KeyColumn("coststructure_id")
            .Cascade.AllDeleteOrphan();

    }
}
public class CostStructureComponentMapping : ClassMap<CostStructureComponent>
{
    public CostStructureComponentMapping()
    {
        Table("CostStructureComponent");

        Id(x => x.Id)
            .Column("id")
            .GeneratedBy.Native();

        References(x => x.CostStructure)
            .Column("coststructure_id");

        References(x => x.ResourceType)
            .Column("resourcetype_id");
    }
}

Nhibernate按我的意图加载关系。但是Mapping的两个部分看起来有点奇怪(或者我的期望很奇怪)。

首先:

 CostStructure structure = new CostStructure() { CardTemplate = template };
 template.CostStructures.Add(structure);
 Session.Save(template);
 Session.Flush();

这不会保存新的CostStructure实例。为什么呢?

第二个:假设我已加载CardTemplateCostStructure包含三个CostStructureComponent个实体。现在,我想从CostStructureComponents中删除其中一个CostStructure 我尝试了以下方法:

costStructure.CostComponents.Remove(component);
component.CostStructure = null;
session.Save(template)

现在,我知道显式删除明确有效,但DeleteOrphan部分是否也应断言现在没有引用CostStructure的组件被删除?相反,NHibernate尝试执行以下更新:

UPDATE CostStructureComponent 
SET amount = @p0, 
     coststructure_id = @p1, 
     resourcetype_id = @p2
WHERE id = @p3;

@p0 = 1 [Type: Int32 (0)], 
@p1 = NULL [Type: Int64 (0)], 
@p2 = 5 [Type: Int64 (0)], 
@p3 = 13 [Type: Int64 (0)]

可能是Equals / GetHashCode以错误的方式实现了吗?

对不起,已经很晚了,过了漫长的一天等等......如果我说的是胡言乱语,请告诉我......

1 个答案:

答案 0 :(得分:1)

所有答案都隐藏在一个设置.Inverse()

public CardTemplateMapping()
{
    HasMany(x => x.CostStructures)
        .KeyColumn("cardtemplate_id")
        .Cascade.All()
        .Inverse(); // HERE this setting

在这里:

public CostStructureMapping()
{
    ..
    HasMany(x => x.CostComponents)
        .KeyColumn("coststructure_id")
        .Cascade.AllDeleteOrphan()
        .Inverse();  // and HERE and everywhere on HasMany()

尝试找一些关于此设置的文章,但一般情况下:如果映射为反向,NHibernate已准备好做更好的SQL语句,因为它正在与其他关系结束...

一些消息来源:

19.5.2. Lists, maps, idbags and sets are the most efficient collections to update 引用:

  

但是,在精心设计的NHibernate域模型中,我们通常会看到大多数集合实际上是one-to-many (注释:HasMany in Fluent) {{1}的关联} 即可。对于这些关联,更新由关联的inverse="true" (注释:Fluent中的引用)结束处理,因此集合更新性能的考虑因素根本不适用。

6.2. Mapping a Collection

  

反向 (可选 - 默认为false)将此集合标记为双向关联的“反向”结尾