Я хочу расширить LINQ-провайдер по умолчанию для NHibernate 3 с помощью своих собственных. Я хочу использовать некоторые методы из своих POCOs. У меня есть компонент Range, который используется довольно часто во многих моих POCOs. Этот NHibernate класс компонент метод содержит (целое значение), которое я хочу использовать в LINQ запроса выраженийNHibernate 3 - расширяющий поставщик Linq BaseHqlGeneratorForMethod.BuildHql проблема
Mapping:
<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-провайдера, но я не знаю, как создавать выражения, необходимые для этого.
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, чтобы построить HqlTreeNode
Вы когда-нибудь получали это? У меня такая же проблема. – BenCr
@BenCr, я так и не получил это - у меня было только 2 места, где я бы использовал это расширение для LINQ. Извините – Vasea
Я изменил свой метод расширения на статический метод, который принимает несколько параметров вместо объекта. Это сработало, но SQL, который генерирует поставщик NHibernate 3 LINQ, не является особенно оптимальным, поэтому я отказался от него в пользу QueryOver api на данный момент. Это, вероятно, менее реалистично, чем LINQ sql, поэтому, вероятно, будет заменен необработанным HQL. – BenCr