问题
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?
回答1:
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.
回答2:
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.
回答3:
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.
回答4:
I agree with Neil, but if you really want this, you can do it with IQuery.ExecuteUpdate()
来源:https://stackoverflow.com/questions/560734/nhibernate-activerecord-how-to-set-foreign-key-without-getting-entire-object