2013-03-19 2 views
0

Рассмотрим связь между этими двумя классамиКак ссылаться на свойства класса и ид отношений в NHibernate

public class Order 
{ 
    public int OrderId {get;set;} 
    public int CustomerId {get;set;} // Should this be here? 
    public Customer Customer{get;set} 
} 

public class Customer 
{ 
    public int CustomerId {get;set;} 
    public string Name {get;set;} 
} 

Я понимаю, что мне не нужно CUSTOMERID собственности на ордена и я согласен что это не самый прекрасный способ сделать что-то. Имея только свойство Клиента, я мог бы легко запросить Order.Customer.CustomerId, чтобы получить Идентификатор Клиента.

Но в этом случае, NHibernate будет инициировать запрос к базе данных, чтобы загрузить клиент и есть некоторые (многие на самом деле) случаи, которые я просто нуждаюсь в CUSTOMERID из ордена. В этом случае CustomerId в классе Прикладной код будет полезен и потребует меньше поездок в базу данных. (Если я ошибаюсь, поправьте меня пожалуйста).

Вопрос 1: есть ли способ сообщить NHibernate, что я хочу, чтобы оба свойства всегда обновлялись?

Свойства CustomerId всегда будет иметь идентификатор Клиента и имущество клиента будет загружен лениво, только если я хочу (скажем, чтобы получить имя клиента). Microsoft Entity Framework позволяет это.

Вопрос 2: Если это невозможно, я должен беспокоиться об этом?

UPDATE

Следуя инструкциям ответы, которые я сделал тест, пытаясь проверить, почему (в моем случае) NHibernate не работает, как ожидалось, и нашел что-то интересное: NHibernate не задевала базу данных по умолчанию при заказе .Customer.CustomerId if Я не использую Accessor.Field mapping свойство CustomerId.

При использовании Accessor по умолчанию он работает должным образом. Любая идея почему?

+0

Вы ошибаетесь в том, что order.customer.id вызывает звонок в базу данных. Я бы рекомендовал отказаться от внешнего ключа. Поэтому q1 и q2 являются избыточными – Rippo

+0

@Rippo: тот же комментарий, который я сделал в ответе penfold: возможно, я что-то делаю неправильно, но в тесте A.B.Id попал в базу данных. Что-то о картировании «много-к-одному»? Хочешь ли? –

+0

@RogerKiihl: Без просмотра сопоставлений и тестового кода невозможно сказать. Можете ли вы обновить свой вопрос с помощью сопоставления для этих классов и тестового кода, который вы использовали? – mickfold

ответ

4

Поведение NHibernate по умолчанию - это не загружать объект при доступе к Id. Другой вопрос уже ответил на этот вопрос here, который я привел ниже.

Если вы извлекаете A из базы данных, то доступ A.B.Id это не попадет в базу данных. Если вы обращаетесь к любому другому свойству, кроме поля Id, это вызовет NHibernate для извлечения B из базы данных.

Так что в итоге делает вызов Order.Customer.CustomerId не вызовет NHibernate для запроса DB для строки в таблице клиентов с этим CustomerId и поэтому лучше, чтобы удалить КодКлиент из вашего класса Order.

+0

Возможно, я что-то делаю неправильно, но в тесте A.B.Id попал в базу данных. Что-то о картировании «много-к-одному»? Хочешь ли? –

+0

После некоторых тестов я смог проверить правильность ответа. Но это поведение по умолчанию работает (до сих пор не знаю почему), когда свойство сопоставленного идентификатора (Customer.CustomerId) использует сопоставление доступа по умолчанию. –

+0

@RogerKiihl Я очень удивлен этим, так как тип доступа не должен влиять на ленивую загрузку. Единственное, что должно повлиять на это, - «lazy =» no-proxy ». – mickfold

1

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

Класс

public int CustomerId {get;set;} // Should this be here? 
public Customer Customer{get;set} // Answer: yes 

Mapping

<many-to-one name="Customer" column="CustomerId" /> 
<property name="CustomerId" column="CustomerId" insert="false" update="false" /> 

Теперь вы можете управлять обоими свойствами в Read операции таким же образом, (например, фильтрация). При попытке снятия заказа необходимо установить Customer, а CustomerId - только для чтения.

Так что для операций записи вы можете (и вы должны) использовать только одно свойство.

Преимущество в том, что если вам нужно фильтровать только КлиентID, вы не должны манипулировать клиента (объект, таблица) на всех.

+0

thx для ответа. Я действительно хочу, чтобы что-то вроде penfold ответили, будет работать (пытаясь). Но ваш подход очень помог! –

Смежные вопросы