Actually, I was wrong. Even CollectionContainsGenerator works with the
extension method. Duh..



2015-09-29 23:15 GMT+02:00 Alexey <gulfst...@gmail.com>:

> Thank you Gunnar. This makes more sense now. I modified *BuildHql()* like
> this:
>
>
> public override HqlTreeNode BuildHql(MethodInfo method, Expression
> targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder
> treeBuilder, IHqlExpressionVisitor visitor)
> {
> var target = targetObject ?? arguments[1];
> var arg = targetObject != null ? arguments[1] : arguments[0];
>
> HqlAlias alias = treeBuilder.Alias("x");
> ParameterExpression param = Expression.Parameter(target.Type, "x");
>
> HqlWhere where =
> treeBuilder.Where(visitor.Visit(Expression.Lambda(Expression.Equal(target,
> param), param)).AsExpression());
>
> return treeBuilder.Exists
> (
> treeBuilder.Query
> (
> treeBuilder.SelectFrom
> (
> treeBuilder.From(treeBuilder.Range(visitor.Visit(arg),alias))
> ),
> where
> )
> );
> }
>
> Now I'm getting an exception:
>
>
> System.NotSupportedException : Specified method is not supported.
>    at
> NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.GetClassName(IASTNode
> querySource)
>    at
> NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.Process(IASTNode
> tree)
>    at NHibernate.Hql.Ast.ANTLR.AstPolymorphicProcessor.Process()
>    at
> NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IASTNode
> ast, String queryIdentifier, String collectionRole, Boolean shallow,
> IDictionary`2 filters, ISessionFactoryImplementor factory)
>    at
> NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression
> queryExpression, Boolean shallow, IDictionary`2 enabledFilters)
>    at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression
> queryExpression, Boolean shallow)
>    at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression
> queryExpression)
>    at NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression
> expression, ref IQuery query, ref NhLinqExpression nhQuery)
>    at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
>    at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
>
>
> Any suggestions?
>
>
> On Monday, September 28, 2015 at 11:15:20 PM UTC-7, Gunnar Liljas wrote:
>>
>> CollectionContainsGenerator works with the instance method Contains,
>> whereas your generator works with the extension method Contains. Target is
>> null, since the extension method is static. The actual "target" is
>> therefore args[0].
>>
>>
>>
>> 2015-09-29 2:53 GMT+02:00 Alexey <gulf...@gmail.com>:
>>
>>> Hi,
>>>
>>> I am trying to create a custom Hql Generator for Collection Contains
>>> which would allow generating Hql from Linq's Contains overload with
>>> IEqualityComparer. It should behave same as CollectionContains on SQL
>>> server, but when expression tree is compiled and executed in memory, I
>>> would like to be able to compare stings
>>> with StringComparer.OrdinalIgnoreCase.
>>>
>>> Essentially I have a working statement
>>>
>>> a => operatorIds.Contains(a.OperatorId);
>>>
>>> which I want to turn into
>>>
>>> a => operatorIds.Contains(a.OperatorId, StringComparer.OrdinalIgnoreCase
>>> );
>>>
>>> I found source code for Collection Contains and modified it like this:
>>>
>>> public class CollectionContainsWithComparerGenerator :
>>> BaseHqlGeneratorForMethod
>>> {
>>> public CollectionContainsWithComparerGenerator()
>>> {
>>> SupportedMethods = new[]
>>> {
>>> ReflectionHelper.GetMethodDefinition(() =>
>>> Enumerable.Contains<object>(null, null, null)),
>>> };
>>> }
>>> public override HqlTreeNode BuildHql(MethodInfo method, Expression
>>> targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder
>>> treeBuilder, IHqlExpressionVisitor visitor)
>>> {
>>> // TODO - alias generator
>>> HqlAlias alias = treeBuilder.Alias("x");
>>>
>>> ParameterExpression param = Expression.Parameter(targetObject.Type, "x");
>>> HqlWhere where = treeBuilder.Where(visitor.Visit(Expression.Lambda(
>>> Expression.Equal(param, arguments[0]), param))
>>>   .AsExpression());
>>>
>>> return treeBuilder.Exists(
>>> treeBuilder.Query(
>>> treeBuilder.SelectFrom(
>>> treeBuilder.From(
>>> treeBuilder.Range(
>>> visitor.Visit(targetObject),
>>> alias)
>>> )
>>> ),
>>> where));
>>> }
>>> }
>>>
>>> Basically, I kept the *BuildHql() *method AS-IS and only modified
>>> signature for *SupportedMethod*. However, this generator throws null
>>> reference exception because *targetObject* is null.
>>>
>>> I noticed that some generators use *targetObject *while others only use 
>>> *arguments
>>> *but I still can't figure out why my generator won't work although it's
>>> identical to CollectionContainsGenerator and how to modify it to fix.
>>>
>>> Any suggestions will help. I couldn't find any documentation on how to
>>> build custom Hql generators.
>>>
>>> Thanks
>>>
>>> --
>>>
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "nhibernate-development" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to nhibernate-development+unsubscr...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>> --
>
> ---
> You received this message because you are subscribed to the Google Groups
> "nhibernate-development" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to nhibernate-development+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 

--- 
You received this message because you are subscribed to the Google Groups 
"nhibernate-development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to nhibernate-development+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to