我有3个相关的对象(Entry,GamePlay,Prize),我试图找到最好的方式来查询他们为我需要使用NHibernate。当有请求进入时,我需要在Entries表中查询匹配的条目,并且如果找到的话,可以得到a)最新的游戏以及附带奖品的第一场游戏。奖品是GamePlay的子项,每个Entry对象都有一个GamePlays属性(IList)。NHibernate标准查询问题
目前,我正在研究一种方法来拉取匹配的条目,并热切地加载所有游戏和相关奖品,但加载所有游戏只是为了找到最新的游戏以及任何包含奖品的游戏似乎是浪费。
现在,我的查询看起来是这样的:
var entry = session.CreateCriteria<Entry>()
.Add(Restrictions.Eq("Phone", phone))
.AddOrder(Order.Desc("Created"))
.SetFetchMode("GamePlays", FetchMode.Join)
.SetMaxResults(1).UniqueResult<Entry>();
两个问题:
- 它加载所有的游戏玩了前面。利用365天的数据,这可以轻松地将每个查询的数据扩展到300k。
- 它并不急于加载每个游戏的奖品属性。因此,我通过GamePlays列表寻找非空奖的代码必须进行调用才能加载我检查的每个Prize属性。
我不是一个nhibernate专家,但我知道必须有一个更好的方法来做到这一点。理想情况下,我想这样做以下(伪):
entry = findEntry(phoneNumber)
lastPlay = getLatestGamePlay(Entry)
firstWinningPlay = getFirstWinningGamePlay(Entry)
当然,最终的结果是,我有条目的详细信息,最新的游戏,和第一个赢取的游戏。问题是我想尽可能少地调用数据库,否则我只执行3个单独的查询。
对象定义是这样的:
public class Entry
{
public Guid Id {get;set;}
public string Phone {get;set;}
public IList<GamePlay> GamePlays {get;set;}
// ... other properties
}
public class GamePlay
{
public Guid Id {get;set;}
public Entry Entry {get;set;}
public Prize Prize {get;set;}
// ... other properties
}
public class Prize
{
public Guid Id {get;set;}
// ... other properties
}
正确的NHibernate的映射到位,所以我只需要帮助搞清楚如何设置的条件查询(不找HQL,不使用它)。
HQl比标准更强大。标准适用于动态查询,HQL适用于复杂的查询。 HQL还有其他的好处,例如你可以将它们存储在预编译的映射文件中。 – 2009-11-24 14:38:13
是的,HQL功能更强大,但它听起来像用户想坚持直接标准。我可以挖掘它。 – 2009-11-24 15:17:49
@Chris:尝试用SQL思考。你会发出什么样的询问以最佳方式获取数据?您可以使用3个带小结果集的查询或带有大结果集的查询。请记住,NHibernate只能生成SQL,它不能以任何其他方式从数据库中获取内容。 – 2009-11-24 15:28:53