【发布时间】:2009-11-24 14:09:56
【问题描述】:
我有 3 个相关对象(Entry、GamePlay、Prize),我正在尝试找到使用 NHibernate 查询它们的最佳方法。当收到请求时,我需要查询 Entries 表以获取匹配的条目,如果找到,则获取 a) 最新的游戏以及第一个附有奖品的游戏。 Prize 是 GamePlay 的子对象,每个 Entry 对象都有一个 GamePlays 属性 (IList)。
目前,我正在研究一种方法,该方法可以拉出匹配的条目并急切地加载所有游戏和相关奖品,但加载所有游戏只是为了找到最新的游戏和任何包含奖品的游戏似乎很浪费。
现在,我的查询如下所示:
var entry = session.CreateCriteria<Entry>()
.Add(Restrictions.Eq("Phone", phone))
.AddOrder(Order.Desc("Created"))
.SetFetchMode("GamePlays", FetchMode.Join)
.SetMaxResults(1).UniqueResult<Entry>();
这有两个问题:
- 它会预先加载所有游戏。有了 365 天的数据,每个查询的数据量很容易膨胀到 30 万。
- 它不会急切地为每个游戏加载 Prize 子属性。因此,我在 GamePlays 列表中循环查找非空 Prize 的代码必须调用以加载我检查的每个 Prize 属性。
我不是休眠专家,但我知道必须有更好的方法来做到这一点。理想情况下,我想做以下(伪代码):
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 比 Criteria 更强大。 Criteria 适合动态查询,HQL 适合复杂查询。 HQL 还有其他好处,例如您可以将它们存储在预编译的映射文件中。
-
是的,HQL 更强大,但听起来用户想要坚持直接的 Criteria。我可以挖那个。
-
@Chris:尝试用 SQL 思考。为了以最佳方式获取数据,您会发出哪些查询?要么使用 3 个带有小结果集的查询,要么使用带有大结果集的查询。请记住,NHibernate 只能生成 SQL,它不能以任何其他方式从数据库中获取内容。
-
@Mike:是的,我想坚持使用强类型查询,因此我不喜欢 HQL。 @Mauricio,我意识到我将不得不以任何一种方式执行查询。有没有办法使用 MultiCriteria 进行相关查询(一个依赖于另一个)?我没有找到太多关于它的文档。
-
@Chris:再一次,用 SQL/RDBMS 术语思考。多条件只是发送到数据库的一批查询,数据库返回一批响应。他们不可能是相关的。
标签: nhibernate