2009-02-18 58 views
3

比方说,我有以下ActiveRecord类:NHibernate/ActiveRecord:如何设置外键而不需要获取整个对象?

[ActiveRecord] 
public class Account 
{ 
    ... 

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

目前,设置在客户现场我必须从数据库中获取整个客户对象,并将其分配给客户的价值:

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

这不是非常有效。我宁愿直接设置CustomerId字段的值,而没有将数据库往返,例如

account.CustomerId = 1; 

这样做的正确方法是什么?

+0

你应该真的提到你在主题中使用NHibrenate。 – 2009-02-18 11:49:26

回答

0

您可以在ActiveRecord中实现MK8k的解决方案。它应该是这样的:

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

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

两个要点:

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

客户类必须定义为懒惰。 NHibernate不会为非惰性类使用代理。

1

这取决于,真的。您可以实施缓存,以减轻获取可能不会像客户那样频繁更改的数据的负担。谨防这可能是不成熟的优化。

2

做,我不知道城堡的ActiveRecord如何使用NHibernate的从数据库加载对象(使用ISession.GetISession.Load?)但我知道,下面就与NHibernate来完成:

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

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

这里,ghostCustomer将是一个未初始化的代理对象,其字段将是懒惰加载被访问的第一次。但是由于我们只用它来分配帐户上的客户关系,它永远不会被加载。

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

相关问题