Заполните несопоставленное свойство объекта домена из результата соединения с Nhibernate - PullRequest
1 голос
/ 07 июня 2010

У меня есть ситуация, когда у меня есть 3 таблицы: StockItem, Office и StockItemPrice. Цена для каждого StockItem может быть разной для каждого офиса.

StockItem(
  ID
  Name
)

Office(
  ID
  Name
)

StockItemPrice(
  ID
  StockItemID
  OfficeID
  Price
)

Я установил схему с двумя отношениями «многие к одному», чтобы связать StockItem и Office. Итак, в моем объекте домена StockItem у меня есть свойство:

IList<StockItemPrice> Prices;

, который загружается с ценой товара для каждого офиса. Это работает нормально. Сейчас я пытаюсь узнать цену товара для одного офиса. У меня следующий запрос Criteria:

NHibernateSession.CreateCriteria(persistentType)  
                 .Add(Restrictions.Eq("ID", id))  
                 .CreateAlias("Prices", "StockItemPrice")  
                 .Add(Restrictions.Eq("StockItemPrice.Office", office))  
                 .UniqueResult<StockItem>();  

Это, кажется, работает нормально, поскольку генерируемый им SQL - это то, чего я мог бы ожидать. Однако я не знаю, правильно ли он заполняет StockItem.Prices одним объектом, как только я ссылаюсь на то, что свойство NHibernate выполняет ленивую загрузку всех цен офиса. Кроме того, даже если он работает, он чувствует себя очень грубо, имея доступ к цене, используя:

mystockitem.Prices[0].Price

Что я действительно хотел бы, так это иметь поле Price на объекте StockItem и иметь цену элемента, помещенную в это поле NHibernate.

Я пытался добавить .CreateCriteria("Price", "StockItemPrice.Price") и то же самое с CreateAlias, но я получаю ошибку

NHibernate.QueryException : could not resolve property: Price of: StockItem

, что, пожалуй, имеет смысл, так как Price не является сопоставленным свойством.

Как бы я изменил запрос, чтобы сделать это возможным?

Ответы [ 2 ]

1 голос
/ 07 июня 2010

Если вы хотите удалить идентификатор из StockItemPrice, вы можете лучше справиться с этим, используя map .

Объявите свойство цен следующим образом:

IDictionary<Office, decimal> Prices { get; set; }

И отобразите это так:

<map name="Prices" lazy="extra">
  <key column="StockItemID" />
  <map-key-many-to-many class="Office" column="OfficeId"/>
  <element type="Decimal" column="Price"/>
</map>

Обратите особое внимание на атрибут lazy="extra".Это означает, что когда вы делаете это:

decimal priceInNY = item.Prices[nyOffice];

Из БД будет получена только цена за nyOffice (экземпляр Office или прокси).

0 голосов
/ 07 июня 2010

Если у вас есть цены на все офисы в собственности Prices, зачем возвращаться в базу данных?

public virtual StockItemPrice GetPriceForOffice(Office office)
{
    return Prices
        .Where(p => o.Office.Equals(office))
        .SingleOrDefault();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...