我正在使用NHibernate到Linq,我有一个已被过滤,排序和预测的可查询。
我正在使用第三方库来使用IQueryable,它处理分页并在其自己的扩展方法中计数
(Telerik Kendo MVC,QueryableExtensions.ToDataSourceResult(this IQueryable enumerable, DataSourceRequest request)
)。
我遇到的问题是在Count上(在ToDataSourceResult黑框中调用)。我收到异常QuerySyntaxException, "A recognition error occurred."
Google搜索表明问题是在预计查询上调用count。 (Google groups post及相关StackOverflow post等)
NH在调用Count之前可以抛弃预测的建议导致我尝试通过使用BaseHqlGeneratorForMethod
和DefaultLinqToHqlGeneratorsRegistry
扩展和注册新生成器来做到这一点。但我在网上找到的所有例子都是为了增加新的功能,而不是替换它。
有没有办法覆盖/替换Count方法NH句柄,以便我可以手动删除投影?
一个附带问题:是否有任何关于将NHibernate-to-Linq扩展的官方文档?我见过this
修改
这是我到目前为止所尝试的内容,而且我没有尝试新的扩展方法。我显然是新手......
public class InteumLinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry
{
public InteumLinqToHqlGeneratorsRegistry()
: base()
{
RegisterGenerator(ReflectionHelper.GetMethod(() => Queryable.Count<object>(null)), new NHibernateCountGenerator());
}
}
public class NHibernateCountGenerator : BaseHqlGeneratorForMethod
{
public NHibernateCountGenerator()
{
SupportedMethods = new[]
{
ReflectionHelper.GetMethod(() => NHibernateCount.InteumCount<object>(null))
};
}
public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
{
return treeBuilder.Count(visitor.Visit(arguments[0]).AsExpression());
}
}
public static class NHibernateCount
{
public static int InteumCount<T>(this IQueryable<T> query)
{
// TODO: Remove projection from query
return query.Count();
}
}
编辑2 事实证明我错过了调用Kendo.Mvc.Extensions.Count(IQueryable)而不是Queryable.Count&lt;&gt;(IQueryable&lt;&gt;)的部分。做了一些改变,仍然,我没有击中HqlGenerator,虽然我仍然不确定它应该击中发电机......
答案 0 :(得分:0)
我已经通过包装IQueryable解决了这种需求。毕竟它只是一个界面。
例如,在lambda项目中,Oracle与“select in”语句一起使用,限制为1000个值。我决定将ISession包装起来,以便为没有任何客户更改(非侵入性)的开发人员包装IQueryable。 在通过NHibernate进行IQueryable评估为IEnumerable之前,我将表达式替换为将所有Contains调用更改为“partition contains”:(。CONTins(...)&amp;&amp; .Contains(...)&amp;&amp; .Contains( ......)&amp;&amp; ...)。
在您的情况下,您可以对IQueryable评估执行相同的单值(IQueryable.Execute)。检测它是否为Count表达式...使用表达式visitor对表达式应用更改,最后将修改后的表达式的计算委托给NHibernate。