NHibernate 3.0:没有使用QueryOver的FirstOrDefault()?

Mar*_*cel 29 linq nhibernate linq-to-nhibernate queryover

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

现在使用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
Run Code Online (Sandbox Code Playgroud)

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

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

Mar*_*cel 36

我现在发现我可以在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
Run Code Online (Sandbox Code Playgroud)

  • 对."Take"是我要推荐的.将它与RRR的`SingleOrDefault`结合使用,而不是`List().FirstOrDefault()`并且它是完美的. (6认同)

小智 22

Result precedingOrMatchingResult = Session.QueryOver<Result>()
                                          .Where(r => r.TimeStamp < timeStamp)
                                          .OrderBy(r => r.TimeStamp).Desc
                                          .SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)

  • 在那种情况下尝试`.Take(1)`之前`.SingleOrDefault()`.见@ Marcel的回答. (11认同)
  • 这不是正确的答案.如果有多个结果,SingleOrDefault会抛出异常.FirstOrDefault没有.你可以尝试.Take(1).SingleOrDefault() (4认同)
  • 导致NHibernate.NonUniqueResultException (3认同)

Die*_*hon 12

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

Result precedingOrMatchingResult = Session.Query<Result>().
    Where(r => r.TimeStamp < timeStamp).
    OrderByDescending(r => r.TimeStamp).
    FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

  • 这不能回答使用QueryOver <T>执行此操作的问题.答案是有效的,不是问题.@ RRR是更正确的. (8认同)

tom*_*ich 10

尝试

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

UniqueResult将返回单个值,如果未找到任何值,则返回null,这与First或Default有关.

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