Я бы посоветовал вам взглянуть на эту проблему с точки зрения NHibernate. И не с точки зрения реляционной базы данных. Позвольте мне начать с того, что, по моему мнению, вы должны делать.
var customer = session.Load<Customer>(3);
var order = session.Load<Order>(1);
order.Customer = customer;
//assuming this is a one directional mapping. otherwise you might
//have to do some more steps to disassociate the order from the old
//customers collection and add it to the new customers collection
session.SaveOrUpdate(order);
Теперь order.Customer.CustomerID
вернет 3.
Как предположил Серкан, лучше и целесообразнее работать с объектами, а не с первичными ключами.
Кроме того, здесь не должно быть никакого влияния на производительность. Nhibernate может проксировать множество ассоциаций, если у классов есть виртуальные открытые методы. Из-за этого, пока вы запрашиваете только Id клиента, он не будет генерировать отдельный SQL-запрос. Идентификатор уже существует с прокси-объектом.
Что касается исходного вопроса, у меня есть догадка. NHibernate динамически генерирует SQL-запрос на обновление и вставки. Этот случай здесь является обновлением. Вы явно установили для свойства CustomerID значение 3. Но свойство Customer объекта заказа по-прежнему указывает на объект customer с идентификатором 1. Таким образом, когда NHibernate создает запрос sql, он пытается установить значение сначала равным 1, как вы и просили. это к. Затем он также видит, что Customer все еще указывает на старый объект, поэтому установите свойство CustomerId равным 1. Я думаю, что NHibernate путают с двойными сопоставлениями.
Есть две вещи, которые вы можете сделать. Сначала включите свойство show_sql в конфигурации NHibernate.
<nhibernate>
...
<add key="hibernate.show_sql" value="true" />
</nhibernate>
Проверьте, что создается sql при сохранении заказа. Это объяснит вещи лучше.
Во-вторых, после сохранения заказа выполните session.Refresh(order);
Вы можете прочитать о методе Refresh () здесь . Это ближе к концу раздела 9.2. Это перезагрузит объект заказа со свежими значениями из базы данных. Вызов order.CustomerID должен показать, какое значение вы сохранили в базе данных.