NHibernate 3-扩展Linq提供程序BaseHqlGeneratorForMethod.BuildHql问题 [英] NHibernate 3 - extending Linq provider BaseHqlGeneratorForMethod.BuildHql problem
问题描述
我想用自己的方法扩展NHibernate 3的默认LINQ提供程序.我希望能够使用我的POCO中的某些方法.我有一个名为Range的组件,在我的许多POCO中都经常使用它.这个nhibernate组件类有一个我想在LINQ查询表达式中使用的方法Contains(int value)
I want to extend the default LINQ provider for NHibernate 3 with methods of my own. I want to be able to use some methods from my POCOs. I have a component named Range which is used quite often in many of my POCOs. This nhibernate component class has a method Contains(int value) that I want to use in LINQ query expressions
映射:
<class name="Foo">
...
<component name="AgeRange">
<property name="Min" column="age_min" />
<property name="Max" column="age_max" />
</component>
</class>
班级
public class Range {
public int Min { get; set; }
public int Max { get; set; }
public bool Contains(int value) {
return value >= this.Min && value <= this.Max;
}
}
// this is the LINQ query I want to be able to write
// which will generate 'SELECT * FROM Foo WHERE 25 BETWEEN age_min AND age_max'
var s = from x in session.Query<Foo> where x.AgeRange.Contains(25) select x;
// I know the following works
var s = from x in session.Query<Foo> where x.AgeRange.Min <= 25 && x.AgeRange.Max >= 25 select x;
我看了几篇博客文章,这些文章解释了如何扩展LINQ提供程序,但是我不知道如何构建使其工作所需的表达式.
I looked at several blog posts explaining how to extend the LINQ provider but I don't know how to build the expressions required for this to work.
public class RangeContainsGenerator : BaseHqlGeneratorForMethod
{
public MemberInfo RangeMin;
public MemberInfo RangeMax;
public RangeContainsGenerator() {
SupportedMethods = new[] {
ReflectionHelper.GetMethodDefinition<Range>(x=> x.Contains(0)),
};
RangeMin = ReflectionHelper.GetProperty<Range, int>(x => x.Min);
RangeMax = ReflectionHelper.GetProperty<Range, int>(x => x.Max);
}
public override NHibernate.Hql.Ast.HqlTreeNode BuildHql(
System.Reflection.MethodInfo method,
System.Linq.Expressions.Expression targetObject,
System.Collections.ObjectModel.ReadOnlyCollection<System.Linq.Expressions.Expression> arguments,
NHibernate.Hql.Ast.HqlTreeBuilder treeBuilder,
NHibernate.Linq.Visitors.IHqlExpressionVisitor visitor) {
// The targetObject parameter contains the "Foo.AgeRange" member access expression
throw new NotImplementedException();
}
}
在BuildHql方法中,我不知道如何访问Range类的Min和Max属性来构建HqlTreeNode
In the BuildHql method I don't know how to access Min and Max properties of my Range class to build a HqlTreeNode
推荐答案
-
您可以使用手动方法:最简单的方法是创建一个代表您想要的内容的LINQ树:
arguments[0] >= targetObject.Min && arguments[1] <= targetObject.Max
.在这里>=
是Expression.GreaterThenOrEqual
,.
是Expression.Property
,依此类推.
You can a manual approach: the easiest way is to create a LINQ tree that represents what you want:
arguments[0] >= targetObject.Min && arguments[1] <= targetObject.Max
. Here>=
isExpression.GreaterThenOrEqual
,.
isExpression.Property
and so on.
当您拥有表达式树时,只需对它应用visitor
并返回它返回的内容(我不记得确切的API,但是如果需要其他帮助,我可以调查一下它).
When you have an expression tree, just apply visitor
to it and return what it returns (I do not remember the exact API, but I can look into it if additional help is needed).
另一个解决方案可能是尝试我的小图书馆:富有表现力.
它尝试将方法IL转换为表达式,因此您可以执行LinqToHqlGeneratorsRegistry
或IRuntimeMethodHqlGenerator
尝试内联 any 未知属性/方法.
Another solution may be to try my little library: Expressive.
It attempts to convert method IL into expressions, so you could do a LinqToHqlGeneratorsRegistry
or IRuntimeMethodHqlGenerator
that tries to inline any unknown property/method.
这篇关于NHibernate 3-扩展Linq提供程序BaseHqlGeneratorForMethod.BuildHql问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!