31

我正在使用 LINQ 提供程序和新的 QueryOver 语法使用 FluentNHibernate 和 NH 3.0。

现在使用 QueryOver 我想获得一个时间戳值尽可能接近给定值但不更大的项目(称为结果):

 Result precedingOrMatchingResult = Session.QueryOver<Result>().
        Where(r => r.TimeStamp < timeStamp).
        OrderBy(r => r.TimeStamp).Desc.                
        FirstOrDefault(); //get the preceding or matching result, if there is any

现在,Intellisense 告诉我,没有FirstOrDefault()方法之类的东西。当然,我可以枚举我的有序查询,然后使用 LINQ 来获取我的项目。但这会首先将所有项目加载到内存中。

是否有替代方法FirstOrDefault(),或者我是否理解完全错误的东西?

4

5 回答 5

39

我现在发现我可以在 IQueryOver 实例上使用 Take() 扩展方法,并且只对列表进行枚举,如下所示:

Result precedingOrMatchingResult = Session.QueryOver<Result>().
        Where(r => r.TimeStamp < timeStamp).
        OrderBy(r => r.TimeStamp).Desc.   
        Take(1).List(). //enumerate only on element of the sequence!
        FirstOrDefault(); //get the preceding or matching result, if there is any
于 2010-12-29T14:04:07.417 回答
23
Result precedingOrMatchingResult = Session.QueryOver<Result>()
                                          .Where(r => r.TimeStamp < timeStamp)
                                          .OrderBy(r => r.TimeStamp).Desc
                                          .SingleOrDefault();
于 2011-08-25T02:03:40.430 回答
12

NH 3 有一个集成的 LINQ 提供程序(查询在内部转换为 HQL/SQL)。您必须添加 NHibernate.Linq 命名空间,然后:

Result precedingOrMatchingResult = Session.Query<Result>().
    Where(r => r.TimeStamp < timeStamp).
    OrderByDescending(r => r.TimeStamp).
    FirstOrDefault();
于 2010-12-29T22:19:43.553 回答
10

尝试

Result precedingOrMatchingResult = Session.QueryOver<Result>().
        Where(r => r.TimeStamp < timeStamp).
        OrderBy(r => r.TimeStamp).Desc.
        SetFetchSize(1).
        UniqueResult();

UniqueResult 将返回一个值,如果没有找到值,则返回 null,这有点像 First 或 Default 所做的。

将 Fetch Size 设置为 1 可能需要也可能不需要,我会使用分析器进行测试。

于 2010-12-29T13:44:09.573 回答
0

SetFetchSize(1)是必须的。如果您的 LINQ 查询返回多个结果,它将使用 抛出 NHibernate 异常UniqueResult(),因为它只期望从查询返回一个结果。

于 2019-04-11T16:15:24.133 回答