NHibernate IQueryable似乎没有延迟执行

lit*_*rva 2 linq nhibernate linq-to-nhibernate

我正在使用NHibernate 3.2,我有一个存储库方法,如下所示:

    public IEnumerable<MyModel> GetActiveMyModel()
    {
        return from m in Session.Query<MyModel>()
               where m.Active == true
               select m;
    }
Run Code Online (Sandbox Code Playgroud)

哪个按预期工作.但是,有时当我使用这种方法时,我想进一步过滤它:

    var models = MyRepository.GetActiveMyModel();
    var filtered = from m in models
                   where m.ID < 100
                   select new { m.Name };
Run Code Online (Sandbox Code Playgroud)

其中产生与第一个相同的SQL,第二个过滤器和选择必须在事后完成.我认为LINQ中的重点是它形成了一个表达树,在需要时它被解开,因此可以创建正确的作业SQL,从而节省了我的数据库请求.

如果没有,这意味着我的所有存储库方法都必须准确地返回所需的内容,并且我不能在不受惩罚的情况下进一步使用LINQ.

我弄错了吗?

更新

响应下面的评论:我省略了迭代结果的行,这导致初始SQL运行(WHERE Active = 1),第二个过滤器(ID <100)显然在.NET中完成.

另外,如果我用第二块代码替换

var models = MyRepository.GetActiveMyModel();
var filtered = from m in models
               where m.Items.Count > 0
               select new { m.Name };
Run Code Online (Sandbox Code Playgroud)

它生成初始SQL以检索活动记录,然后为每条记录运行一个单独的SQL语句,以找出它有多少项,而不是像我期望的那样写一些东西:

SELECT Name 
FROM MyModel m 
WHERE Active = 1 
    AND (SELECT COUNT(*) FROM Items WHERE MyModelID = m.ID) > 0
Run Code Online (Sandbox Code Playgroud)

安东尼

Bry*_*tts 7

IEnumerable<MyModel>将从该方法返回,这将导致从该点开始的内存中评估,即使基础序列是IQueryable<MyModel>.

如果要在GetActiveMyModel添加到SQL查询后允许代码,请返回IQueryable<MyModel>.

  • @littlecharva:有时只需要第二眼. (3认同)