gpt4 book ai didi

c# - NHibernate SaveOrUpdate 子集合未使用标识 ID 更新

转载 作者:可可西里 更新时间:2023-11-01 08:58:34 24 4
gpt4 key购买 nike

我显然遗漏了一些东西(希望很明显),到目前为止我在 Google 上运气不好。

我有一个父子关系映射如下

简化的父 map

  public sealed class ParentMap : ClassMap<ParentEntity>
{
public ParentMap()
{
Table("Parent");
Component(x => x.Thumbprint);
Id(x => x.Id).GeneratedBy.Identity();

Map(x => x.ServeralNotNullableProperties).Not.Nullable();

HasMany(x => x.Children).KeyColumn("ChildId")
.Inverse()
.LazyLoad()
.Cascade
.AllDeleteOrphan();

References(x => x.SomeUnrelatedLookupColumn).Column("LookupColumnId").Not.Nullable();
}
}

简化子图

  public sealed class ChildMap : ClassMap<ChildEntity>
{
public ChildMap()
{
Table("Child");
Component(x => x.Thumbprint);
Id(x => x.Id).GeneratedBy.Identity();

Map(x => x.MoreNotNullableProperties).Not.Nullable();

References(x => x.Parent).Column("ParentId").Not.Nullable();
}
}

简化的服务方法步骤

然后我有一个服务方法,它检索 Parent 并通过一些域方法添加一个新的 Child。底层的 NHibernate 代码归结为:

1) 在 WCF AfterReceiveRequest (IDispatchMessageInspector) 上打开 session

_sessionFactory.OpenSession();

2) 通过 .Query 检索现有的 parent 实例

_session.Query<ParentEntity>()
.Where(item => item.Id == parentId)
.Fetch(item => item.SomeLookupColumn)
.First();

3) 通过域对象方法将新的“子”实体添加到“父”,例如...

public ChildEntity CreateChild()
{
var child = new ChildEntity{ Parent = this };

Children.Add(child);

return child;
}

4) 最终调用“父”实体上的 SaveOrUpdate。

 // ChildEntity Id is 0
_session.SaveOrUpdate(parentEntity)
// Expect ChildEntity Id to NOT be 0

注意:使用 SaveOrUpdate Does 将更改保存到数据库;使用 Merge 会导致下面提到的 TransientObjectException。

5) 最后,事务在 WCF BeforeSendReply (IDispatchMessageInspector) 上提交

 _session.Commit();

问题

通常在保存实体时,在调用 SaveOrUpdate 之后,所述实体的 Id 反射(reflect)由 INSERT 语句生成的身份。但是,当我将新的子实体添加到现有父实体时,Children 中的关联实体未分配 ID。我需要将此 ID 传递回调用方,以便后续调用导致更新而不是额外的插入。

为什么 NHibernate 不更新底层实体?我是否明确必须对 child 调用 SaveOrUpdate(如果是这种情况,那很糟糕)?

对此事的任何想法都非常感谢。谢谢!

编辑我应该注意,新的子实体正在按预期保存;我只是没有取回分配的 ID。

更新尝试按照下面 Michael Buen 的建议切换到 .Merge(~) ;导致 TransientObjectException 告诉我在调用合并之前显式保存修改后的子实体。我也尝试过 .Persist(~) 无济于事。非常感谢任何额外的见解。

object is an unsaved transient instance - save the transient instance before merging: My.NameSpace.ChildEntity

最佳答案

我终于抽出时间来研究 NHibernate 代码……发生这种情况的原因是有道理的……简短的回答——级联操作是在 Session.Commit() 上处理的;在上述服务操作完成后。因此,在服务方法返回更新后的子实体时,我的子对象尚未刷新以反射(reflect)分配的 ID。

事实证明,如果我需要立即知道 Id,我必须直接在子实体上调用 SaveOrUpdate。

关于c# - NHibernate SaveOrUpdate 子集合未使用标识 ID 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5629358/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com