NHibernate/ActiveRecord - 有什么方法可以只映射到外键列?

发布于 2024-07-09 03:22:18 字数 1047 浏览 7 评论 0原文

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

TableA -hasMany-> TableB

我有对应的对象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 类对象,并且我们希望这些页面包含指向相应父页面的链接(如超链接)。 我们可以使用上面的第一种方法来做到这一点,但这需要加载整个 EntityA 对象,而我真正需要的只是 ID。 这不是什么大事,但似乎很浪费。 我知道我可以使用延迟加载,但同样,这对我来说更像是一种黑客......

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

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

这种方法的问题是 EntityB.ParentId 仍然存在当您在新对象树上执行 EntityA.SaveAndFlush() 时,返回 null。 正确的值正在写入数据库,我可以通过执行 EntityA.Refresh() 将值强制返回 EntityB.ParentId,但同样,这看起来有点像黑客。

I'm using Castle ActiveRecord, but this question applies to NHibernate, too, since a solution that works with NHibernate should work for ActiveRecord. Anyway, what I have is an underlying table structure like this:

TableA -hasMany-> TableB

I have corresponding objects EntityA and EntityB. EntityA has an IList of EntityB objects. This part works fine. Now, I want EntityB to have some kind of reference back to EntityA. I know I can use the BelongsTo attribute on EntityB to give it an actual reference back to the full EntityA type, like:

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

But what I'd really like to do is:

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

So, EntityB would store only the ID of the parent object, not a reference to the actual object. This is a trivial example, but I have good reasons for wanting to go with this approach. In the application I'm working on, we have pages that display specific EntityB-like objects, and we'd like for those pages to include links (as in hyperlinks) to the corresponding parent pages. We can do that by using the first approach above, but that requires that the entire EntityA object be loaded when all I really need is the ID. It's not a huge deal, but it just seems wasteful. I know I can use lazy-loading, but again, that seems more like a hack to me...

I have tried flagging the foreign key with the [Property] attribute like so:

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

The problem with this approach is that EntityB.ParentId remains null when you do a EntityA.SaveAndFlush() on a new object tree. The correct value is being written to the database, and I can force the value back into EntityB.ParentId by doing an EntityA.Refresh(), but again, that seems like a bit of a hack.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

脱离于你 2024-07-16 03:22:18

延迟加载正是您想要的 - 而且它也不是黑客,它是 NHIbernate 中经过充分测试和烘焙的部分,并且是调整任何重要 NHibernate 应用程序性能时的重要工具。

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

Lazy loading is exactly what you want - and it's not a hack either, it's a well tested and baked in part of NHIbernate and an important tool when performance tuning any substantial NHibernate app.

If you were to mark your "parent" EntityA as lazy loaded, referring to EntityB.Parent.Id would not load EntityA at all (as behind the scenes NHIbernate has already loaded EntityA's id when loading EntityB) - thus letting you setup your links without incurring a performance penalty.

捂风挽笑 2024-07-16 03:22:18

只是这样:

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

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

其他一些评论。

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

其次,请注意,每当您有一对多关联且从子项到父项没有对应关系时,您必须在数据库中将 FK 设为可为空。 这是因为当 NH 创建新的子项时,它将插入父项 id 为 null 的子项,然后在第二步中更新它。

Just this:

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

...assuming ParentId is the actual column name.

A couple of other comments.

First, you should consider lazy loading many-to-one properties anyway. If you eagerly load them, you must be aware of possible cascades of eager loads, which can make a serious performance hit. To do this you must mark all public members of the lazily loaded class as virtual.

Second, be aware that any time you have a one-to-many association with no corresponding relation from the child back to the parent, you must make the FK nullable in the database. That's because when NH creates new child items, it will insert it with the parent id null and then in a second step update it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文