简体   繁体   English

NHibernate什么时候执行我的查询?

[英]When does NHibernate execute my query?

I am trying to write a generic repository for my NHibernate data access. 我试图为我的NHibernate数据访问编写一个通用存储库。 The Get<T>() method should be able to take an optional predicate, that should be included in the query - that is, NHibernate should generate the WHERE clause in the SQL. 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();

    }

When I pass in a predicate, and observe the SQL statement NH generates, I see no where clause. 当我传入一个谓词并观察NH生成的SQL语句时,我看不到where子句。

When does NHibernate execute the query? NHibernate何时执行查询? Right when calling .Query<T>() ? 在调用.Query<T>()吗? If so, how can I achieve this? 如果是这样,我该如何实现?

The query should be executed by the call ToList() . 该查询应通过调用ToList()来执行。

The case why the WHERE clause is not included in your sql statement is that you need to pass an Expression<Func<T,bool>> to your method. 为什么WHERE子句不包含在您的sql语句中,是因为您需要将Expression<Func<T,bool>>传递给您的方法。

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();

    }

The extension method Where(Func<T,bool>>) is defined on Enumerable , so that the the query loads all data and then applies the WHERE-filter in memory. 扩展方法Where(Func<T,bool>>)Enumerable上定义,以便查询加载所有数据,然后在内存中应用WHERE过滤器。

The extension method Where(Expression<Func<T,bool>>) is defined on Queryable , so that the query provider (NHibernate) can build a sql statement including your WHERE condition that gets executed on the data source. 扩展方法Where(Expression<Func<T,bool>>)是在Queryable上定义的,以便查询提供程序(NHibernate)可以构建一个包含在数据源上执行的WHERE条件的sql语句。

Since @Jehof gave you correct explanation I just want to add separate note - you should not return IList<T> from you repository method as then any other linq operation will be executed in memory and not in the database. 因为@Jehof给了您正确的解释,所以我只想添加单独的注释-您不应从存储库方法返回IList<T> ,因为其他任何linq操作都将在内存中而不是数据库中执行。 Assume following calls 接听电话

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

so now if you have IList<T> Get<T>() you decrease performance but with IQueryable<T> Get<T> you would still have the second Where() appended to the database query. 因此,现在如果您具有IList<T> Get<T>()会降低性能,但是使用IQueryable<T> Get<T>您仍将第二个Where()附加到数据库查询中。

Of course not all linq operations are supported by IQueryable like (join , last ) and this is the only place to call ToList() extension to evaluate expression. 当然,并非所有linq操作都受IQueryable支持,例如(join,last),并且这是调用ToList()扩展来评估表达式的唯一位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM