C# 使用自定义hql生成器将linq扩展到nhibernate

C# 使用自定义hql生成器将linq扩展到nhibernate,c#,nhibernate,linq-to-nhibernate,C#,Nhibernate,Linq To Nhibernate,目标是使用NHibernate和Linq执行类似的操作: Session.Query().Where(x=>x.DateGreaterThen(DateTime.Now)) 这个例子稍微简化了一点,但其思想是在Where谓词中我想调用MyClass方法。所以MyClass看起来像: 公共类MyClass { 公共静态只读表达式更大的表达式= (x,dt)=>x.MyDateTimeProperty>dt.Date; 私有静态只读Func GreaterThenFunc=GreaterThenE

目标是使用NHibernate和Linq执行类似的操作:

Session.Query().Where(x=>x.DateGreaterThen(DateTime.Now))
这个例子稍微简化了一点,但其思想是在Where谓词中我想调用MyClass方法。所以MyClass看起来像:

公共类MyClass
{
公共静态只读表达式更大的表达式=
(x,dt)=>x.MyDateTimeProperty>dt.Date;
私有静态只读Func GreaterThenFunc=GreaterThenExpression.Compile();
公共Guid Id{get;set;}
公共日期时间MyDateTimeProperty{get;set;}
公共bool DateGreaterThen(DateTime dt)
{
返回GreaterThenFunc(this,dt);
}
}
自定义生成器:

公共类EntityMethodGenerator:BasehqlGeneratorFormMethod
{
私有表达式_returnValueExpression;
公共实体方法生成器()
{
SupportedMethods=new[]
{
ReflectionHelper.GetMethodDefinition(myClass=>myClass.DateGreaterThen(DateTime.Now))
};
}
公共静态无效寄存器(ILinqToHqlGeneratorsRegistry注册表,表达式方法,表达式returnValueExpression)
{
var生成器=新EntityMethodGenerator{{U returnValueExpression=returnValueExpression};
registry.RegisterGenerator(ReflectionHelper.GetMethodDefinition(方法),生成器);
}
公共覆盖HqlTreeNode BuildHql(
MethodInfo方法,
表达式targetObject,
只读集合参数,
HqlTreeBuilder treeBuilder,
IHQL表达(访客)
{
回访者。访问(_returnValueExpression);
}
}
最后是自定义生成器注册表:

公共类OwnLinqToHqlGeneratorsRegistry:DefaultLinqToHqlGeneratorsRegistry
{
公有LinqToHqlGeneratorsRegistry()
{
EntityMethodGenerator.Register(this,(myClass)=>myClass.DateGreaterThen(DateTime.Now),myClass.GreaterThenExpression);
}   
}
但是这不起作用,我得到了
System.Data.SqlClient.SqlException:无效的列名“dt”。
我怀疑我的BuildHql方法没有正确实现,有没有帮助解决这个问题


顺便说一下,我想在生成器中使用表达式,比如我的
greatertenexpression
,而不是在
BuildHql
方法中手动构建HqlTree

greatertenexpression是lamba。在BuildHql()中,您还需要注意targetObject和参数,否则您只是在HQL树中插入一些未应用lambda的HQL转换

您需要提取lambda的主体,并用targetObject和参数替换其参数。然后您可以从中生成HQL。尝试使用Remotion.Linq.Parsing.ExpressionTreeVisitors.MultiReplacingExpressionTreeVisitor

(在旁注中,它应该大于,而不是大于。)