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.