我有以下映射类(仅复制相关部分):
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
实例。为什么呢?
第二个:假设我已加载CardTemplate
,CostStructure
包含三个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以错误的方式实现了吗?
对不起,已经很晚了,过了漫长的一天等等......如果我说的是胡言乱语,请告诉我......
答案 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中的引用)结束处理,因此集合更新性能的考虑因素根本不适用。
反向 (可选 - 默认为false)将此集合标记为双向关联的“反向”结尾