【问题标题】:When does NHibernate execute my query?NHibernate 什么时候执行我的查询?
【发布时间】:2013-03-22 08:44:51
【问题描述】:

我正在尝试为我的 NHibernate 数据访问编写一个通用存储库。 Get<T>() 方法应该能够接受一个可选的谓词,该谓词应该包含在查询中——也就是说,NHibernate 应该在 SQL 中生成 WHERE 子句。

    public virtual IList<T> Get(Func<T, bool> predicate = null)
    {
        // Open NHibernate Session
        using (var session = NHibernateHelper.OpenSession())
            return (predicate != null
                       ? session.Query<T>().Where(predicate)
                       : session.Query<T>()).ToList();

    }

当我传入一个谓词并观察 NH 生成的 SQL 语句时,我看不到 where 子句。

NHibernate 什么时候执行查询?打电话给.Query&lt;T&gt;()的时候对吗?如果是这样,我该如何实现?

【问题讨论】:

    标签: c# linq nhibernate


    【解决方案1】:

    查询应该通过调用ToList()来执行。

    WHERE 子句未包含在您的 sql 语句中的情况是您需要将 Expression&lt;Func&lt;T,bool&gt;&gt; 传递给您的方法。

    public virtual IList<T> Get(Expression<Func<T, bool>> predicate = null)
        {
            // Open NHibernate Session
            using (var session = NHibernateHelper.OpenSession())
                return (predicate != null
                           ? session.Query<T>().Where(predicate)
                           : session.Query<T>()).ToList();
    
        }
    

    Enumerable 上定义了扩展方法Where(Func&lt;T,bool&gt;&gt;),以便查询加载所有数据,然后在内存中应用 WHERE 过滤器。

    Queryable 上定义了扩展方法 Where(Expression&lt;Func&lt;T,bool&gt;&gt;),以便查询提供程序 (NHibernate) 可以构建一个包含在数据源上执行的 WHERE 条件的 sql 语句。

    【讨论】:

    • 谢谢,绝对完美!
    【解决方案2】:

    由于@Jehof 给了你正确的解释,我只想添加单独的注释 - 你不应该从你的存储库方法返回IList&lt;T&gt;,因为任何其他 linq 操作都将在内存中而不是在数据库中执行。假设以下调用

    var data = repository.Get<Company>(c=>c.Name.StartsWith("MyCompany"));
    ... some other operations / method calls etc.
    var companySubset = data.Where(...);
    

    所以现在如果你有 IList&lt;T&gt; Get&lt;T&gt;() 会降低性能,但使用 IQueryable&lt;T&gt; Get&lt;T&gt; 你仍然会将第二个 Where() 附加到数据库查询中。

    当然,IQueryable 并不支持所有 linq 操作,例如 (join , last ),这是唯一调用 ToList() 扩展来评估表达式的地方。

    【讨论】:

    • 这就是重点,但感谢您的注意 :) - 当我没有明确要求时,我不希望我的业务逻辑触发数据库调用。
    猜你喜欢
    • 2021-12-30
    • 1970-01-01
    • 2011-11-04
    • 2021-08-08
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多