NHibernate / ActiveRecord:如何在不获取整个对象的情况下设置外键?

发布于 2024-07-14 07:51:02 字数 472 浏览 9 评论 0原文

假设我有以下 ActiveRecord 类:

[ActiveRecord]
public class Account
{
    ...

    [BelongsTo("CustomerId")]
    public Customer Customer { get; set; }
}

目前,要设置 CustomerId 字段的值,我必须从数据库获取整个 Customer 对象并将其分配给 Account:

Customer customer = Customer.FindById(1);
account.Customer = customer;

这不是很有效。 我宁愿直接设置 CustomerId 字段的值,而不需要往返数据库,例如

account.CustomerId = 1;

执行此操作的正确方法是什么?

Let's say I've got the following ActiveRecord class:

[ActiveRecord]
public class Account
{
    ...

    [BelongsTo("CustomerId")]
    public Customer Customer { get; set; }
}

Currently, to set the value of the CustomerId field I have to get the entire Customer object from the database and assign it to the Account:

Customer customer = Customer.FindById(1);
account.Customer = customer;

This isn't very efficient. I'd rather set the value of CustomerId field directly without round-tripping the database, e.g.

account.CustomerId = 1;

What's the correct way to do this?

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

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

发布评论

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

评论(4

荆棘i 2024-07-21 07:51:02

我不知道Castle ActiveRecord如何使用NHibernate从数据库加载对象(使用ISession.GetISession.Load?),但我知道以下可以是使用 NHibernate 完成:

var ghostCustomer = session.Load<Customer>(customerId);

var account = session.Get<Account>(accountId);
account.Customer = ghostCustomer;

这里,ghostCustomer 将是一个统一的代理对象,其字段将在第一次访问时延迟加载。 但由于我们仅使用它来分配帐户上的客户关系,因此它永远不会实际加载。

因此,此示例中唯一的数据库访问将在加载帐户时以及之后刷新会话并且必须更新帐户时发生。

I don't know how Castle ActiveRecord uses NHibernate to load objects from the database (using ISession.Get or ISession.Load?), but I know that the following can be done with NHibernate:

var ghostCustomer = session.Load<Customer>(customerId);

var account = session.Get<Account>(accountId);
account.Customer = ghostCustomer;

Here, ghostCustomer will be an unitialized proxy object, whose fields will be lazy loaded the first time they are accessed. But since we only use it to assign the customer relation on the account, it will never actually be loaded.

Thus, the only database access in this example will happen when loading the account and afterwards when the session is flushed and the account must be updated.

太阳男子 2024-07-21 07:51:02

这取决于,真的。 您可以实施缓存来减轻获取数据的负担,这些数据可能不会像客户那样经常更改。 但请注意,这可能是不成熟的优化。

It depends, really. You can implement caching to lessen the burden of obtaining data that might not change too often like customers. Beware this might be premature optimisation though.

一杯敬自由 2024-07-21 07:51:02

我同意尼尔的观点,但如果你真的想要这个,你可以用 IQuery.ExecuteUpdate( )

I agree with Neil, but if you really want this, you can do it with IQuery.ExecuteUpdate()

心不设防 2024-07-21 07:51:02

您可以在ActiveRecord中实现MK8k的解决方案。 它看起来像这样:

using (new SessionScope()) {
    var ghostCustomer = Customer.Find(customerId);

    var account = Account.TryFind(accountId);
    account.Customer = ghostCustomer;
}

两个要点:

Customer.Find 必须位于 SessionScope 中。 如果未定义 SessionScope,Find 方法将检查并完全加载您的对象。

Customer 类必须定义为惰性类。 NHibernate 不会对非惰性类使用代理。

You can implement MK8k's solution in ActiveRecord. It would look like this:

using (new SessionScope()) {
    var ghostCustomer = Customer.Find(customerId);

    var account = Account.TryFind(accountId);
    account.Customer = ghostCustomer;
}

Two important points:

The Customer.Find must be in a SessionScope. The Find method checks and will fully load your object if a SessionScope is not defined.

The Customer class must be defined as lazy. NHibernate will not use a proxy for a non-lazy class.

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