0

我正在使用 Castle ActiveRecord,但这个问题也适用于 NHibernate,因为适用于 NHibernate 的解决方案应该适用于 ActiveRecord。无论如何,我拥有的是这样的底层表结构:

表A -hasMany-> 表B

我有相应的对象 EntityA 和 EntityB。EntityA 有一个 EntityB 对象的 IList。这部分工作正常。现在,我希望 EntityB 对 EntityA 有某种引用。我知道我可以使用 EntityB 上的 BelongsTo 属性为其提供对完整 EntityA 类型的实际引用,例如:

[BelongsTo("tableAid")]
public EntityA Parent { get; set; }

但我真正想做的是:

[BelongsTo("tableAid")]
public int ParentId { get; set; }

因此,EntityB 将仅存储父对象的 ID,而不是对实际对象的引用。这是一个微不足道的例子,但我有充分的理由想要采用这种方法。在我正在处理的应用程序中,我们有显示特定 EntityB 类对象的页面,我们希望这些页面包含指向相应父页面的链接(如超链接中的链接)。我们可以使用上面的第一种方法来做到这一点,但这需要在我真正需要的只是 ID 时加载整个 EntityA 对象。这不是什么大不了的事,但似乎很浪费。我知道我可以使用延迟加载,但同样,这对我来说更像是一种黑客行为......

我尝试使用 [Property] 属性标记外键,如下所示:

[Property]
public int ParentId { get; set; }

这种方法的问题在于,当您在新对象树上执行 EntityA.SaveAndFlush() 时,EntityB.ParentId 仍然为空。正确的值被写入数据库,我可以通过执行 EntityA.Refresh() 将值强制回 EntityB.ParentId,但同样,这似乎有点像 hack。

4

2 回答 2

2

延迟加载正是您想要的——它也不是一个 hack,它在 NHIbernate 的一部分中经过了良好的测试和烘焙,并且是调整任何实质性 NHibernate 应用程序性能时的重要工具。

如果您要将您的“父”EntityA 标记为延迟加载,则引用 EntityB.Parent.Id 根本不会加载 EntityA(因为在幕后 NHIbernate 在加载 EntityB 时已经加载了 EntityA 的 id) - 从而让您无需设置链接即可招致性能损失。

于 2009-05-03T11:57:23.820 回答
0

只是这个:

[Property] public int ParentId { get; set; }

...假设ParentId是实际的列名。

其他一些评论。

首先,您应该考虑延迟加载多对一属性。如果您急切地加载它们,您必须意识到急切加载可能的级联,这可能会严重影响性能。为此,您必须将延迟加载的类的所有公共成员标记为虚拟。

其次,请注意,任何时候您有一个一对多的关联,而没有从子级到父级的对应关系,您必须使数据库中的 FK 可以为空。这是因为当 NH 创建新的子项目时,它会将其插入其父 id 为 null,然后在第二步中对其进行更新。

于 2008-10-29T14:22:55.370 回答