使用Nhibernate从连接结果填充域对象的未映射属性

时间:2010-06-07 11:14:12

标签: asp.net nhibernate

我的情况是我有3个表:StockItem,Office和StockItemPrice。每个StockItem的价格可能因每个Office而异。

StockItem(
  ID
  Name
)

Office(
  ID
  Name
)

StockItemPrice(
  ID
  StockItemID
  OfficeID
  Price
)

我已经建立了一个包含2个多对一关系的模式来链接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

我真正想要的是在StockItem对象上有一个Price字段,并且NHIBnate将该项目的价格放入该字段。

我尝试添加.CreateCriteria("Price", "StockItemPrice.Price")和CreateAlias相同,但我收到了错误

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

这是有道理的,因为Price不是映射属性。

如何调整查询以使其成为可能?

2 个答案:

答案 0 :(得分:1)

如果您愿意从StockItemPrice中删除ID,则可以使用地图更好地处理此问题。

按如下方式声明您的价格属性:

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实例或代理)的价格。

答案 1 :(得分:0)

如果您拥有Prices属性中所有办公室的价格,为什么还要回到数据库?

public virtual StockItemPrice GetPriceForOffice(Office office)
{
    return Prices
        .Where(p => o.Office.Equals(office))
        .SingleOrDefault();
}