[英]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.