NHibernate / ActiveRecord: как установить внешний ключ без получения всего объекта? - PullRequest
3 голосов
/ 18 февраля 2009

Допустим, у меня есть следующий класс ActiveRecord:

[ActiveRecord]
public class Account
{
    ...

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

В настоящее время, чтобы установить значение поля CustomerId, я должен получить весь объект Customer из базы данных и назначить его учетной записи:

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

Это не очень эффективно. Я бы предпочел установить значение поля CustomerId напрямую, без обхода базы данных, например

account.CustomerId = 1;

Как правильно это сделать?

Ответы [ 4 ]

2 голосов
/ 25 февраля 2009

Я не знаю, как Castle ActiveRecord использует NHibernate для загрузки объектов из базы данных (используя ISession.Get или ISession.Load?), Но я знаю, что с NHibernate можно сделать следующее:

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

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

Здесь ghostCustomer будет унитарным прокси-объектом, поля которого будут загружаться с отложенной загрузкой при первом обращении к ним. Но поскольку мы используем его только для назначения отношения с клиентом в учетной записи, он никогда не будет загружен.

Таким образом, единственный доступ к базе данных в этом примере будет происходить при загрузке учетной записи и впоследствии, когда сеанс сбрасывается и учетная запись должна быть обновлена.

1 голос
/ 19 февраля 2009

Я согласен с Нилом, но если вы действительно этого хотите, вы можете сделать это с помощью IQuery.ExecuteUpdate ()

1 голос
/ 18 февраля 2009

Это зависит, действительно. Вы можете внедрить кэширование, чтобы уменьшить нагрузку на получение данных, которые могут меняться не так часто, как клиенты. Осторожно, это может быть преждевременной оптимизацией.

0 голосов
/ 23 октября 2010

Вы можете реализовать решение MK8k в ActiveRecord. Это будет выглядеть так:

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

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

Два важных момента:

Customer.Find должен быть в SessionScope. Метод Find проверяет и полностью загружает ваш объект, если SessionScope не определен.

Класс Customer должен быть определен как ленивый. NHibernate не будет использовать прокси для не ленивых классов.

...