2008-10-29 76 views
0

我正在使用Castle ActiveRecord,但这个问题也适用于NHibernate,因为与NHibernate一起工作的解决方案应该可以用于ActiveRecord。不管怎么说,我有一个潜在的表结构是这样的:NHibernate的/ ActiveRecord的 - 任何方式只映射到外键列?

表A -hasMany->表B

我有相应的对象EntityA和EntityB。 EntityA拥有一个EntityB对象的IList。这部分工作正常。现在,我希望EntityB拥有某种对EntityA的引用。我知道我可以使用EntityB的属于关联属性给它一个实际参考回满EntityA类型,如:

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

但我真的很想做的是:

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

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

我曾尝试与标记的[属性]外键的属性,像这样:

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

这种方法的问题是当您在新的对象树上执行EntityA.SaveAndFlush()时,EntityB.ParentId保持为空。正确的值被写入到数据库中,我可以通过EntityA.Refresh()强制将值返回到EntityB.ParentId中,但是再次,这看起来有点像黑客。

回答

2

懒惰加载正是你想要的 - 它也不是黑客,它是一个经过良好测试和烘焙的NHIbernate的一部分,当性能调整任何实质的NHibernate应用程序时,它是一个重要的工具。

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

0

就在:

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

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

其他评论。

首先,您应该考虑延迟加载多对一的属性。如果你急切地加载它们,你必须意识到可能的负载级联,这可能会导致严重的性能下降。要做到这一点,您必须将所有懒惰加载类的公共成员标记为虚拟。

其次,请注意,只要您有一个一对多的关联关系并且没有从孩子回到父母的对应关系,就必须在数据库中使FK为空。这是因为当NH创建新的子项目时,它会将其插入到父ID为null的位置,然后在第二步中更新它。

+0

感谢您的建议。我实际上已经尝试过这种方法,但我忘了在问题中列出它。它主要工作,但不完美。 :( – 2008-10-29 21:18:30