NHibernate 3 - Linq Provider Extension BaseHqlGeneratorForMethod.BuildHql Problem

I want to extend the default LINQ provider for NHibernate 3 using my own. I want to use some methods from my POCOs. I have a Range component that is used quite often in many of my POCOs. This nhibernate component class has a Contains (int value) method that I want to use in LINQ query expressions

Mapping:

<class name="Foo"> ... <component name="AgeRange"> <property name="Min" column="age_min" /> <property name="Max" column="age_max" /> </component> </class> 

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; 

I looked at a few blog posts explaining how to extend the LINQ provider, but I don't know how to create the expressions needed for this.

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

In the BuildHql method, I don't know how to access the Min and Max properties of my Range class to create an HqlTreeNode

+4
source share
2 answers
  • You can use 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 >= there is Expression.GreaterThenOrEqual is Expression.Property , etc.

    When you have an expression tree, just apply a visitor to it and return what it returns (I don’t remember the exact API, but I can study it if I need additional help).

  • Another solution is to try my little library: Expressive .
    It tries to convert the IL method to expressions, so you can make a LinqToHqlGeneratorsRegistry or IRuntimeMethodHqlGenerator that tries to inject any unknown property / method.

+2
source

There are some good examples of a LINQ provider extension here: http://www.primordialcode.com/

+1
source

All Articles