c# - Custom SQLFunctionTemplate on XML field causes escaping error if a Skip(..) LINQ section follows -
i have created custom sqlfunctiontemplate query xml field specific name/value pairs:
registerfunction("_existincaratteristiche", new sqlfunctiontemplate(nhibernateutil.boolean, "?1.exist('/l/i/c[n=sql:variable(\"?2\") , v=sql:variable(\"?3\")]') = 1"));
which use this:
private iqueryable<myentity> _xmlfilter(iqueryable<myentity> input, string element, string value) { if (string.isnullorempty(element) || string.isnullorempty(value)) return input; return input.where(m => m.xmlfield.xmlcontains(element.toupper(),value)); }
and so, can do:
.. iqueryable<myentity> result = session.query<myentity>(); result = _xmlfilter(result, filter.element, filter.value); return result.tolist(); ..
this working correctly.
unfortunately, if add skip linq section after custom filter, this:
.. iqueryable<myentity> result = session.query<myentity>(); result = _xmlfilter(result, filter.element, filter.value); result = result.skip(3); return result.tolist(); ..
i following error when result.tolist() called:
cannot find terminating ''' character quoted text.
i think i'm facing escaping problem have no idea why happens if add skip linq section. tried various combinations of quotes , single quotes in sqlfunctiontemplate wasn't able solve issue.
as requested oskar berggren, here's full stack-trace of exception, thrown nhibernate
tries convert iqueryable
appropriate query (which when .tolist()
invoked)
nhibernate.exceptions.sqlparseexception: cannot find terminating ''' character quoted text. @ nhibernate.sqlcommand.parser.sqlparserutils.readdelimitedtext(string text, int32 maxoffset, int32 offset) @ nhibernate.sqlcommand.parser.sqltokenizer.<getenumerator>d__0.movenext() @ nhibernate.sqlcommand.parser.sqltokenizerextensions.tryparseuntil(ienumerator`1 tokenenum, string keyword) @ nhibernate.sqlcommand.parser.sqltokenizerextensions.tryparseuntilfirstordercolumn(ienumerator`1 tokenenum, sqltoken& ordertoken) @ nhibernate.sqlcommand.parser.mssqlselectparser..ctor(sqlstring sql) @ nhibernate.dialect.mssql2005dialectquerypager.pagebylimitandoffset(sqlstring offset, sqlstring limit) @ nhibernate.dialect.mssql2005dialectquerypager.pageby(sqlstring offset, sqlstring limit) @ nhibernate.dialect.mssql2005dialect.getlimitstring(sqlstring querystring, sqlstring offset, sqlstring limit) @ nhibernate.dialect.dialect.getlimitstring(sqlstring querystring, nullable`1 offset, nullable`1 limit, parameter offsetparameter, parameter limitparameter) @ nhibernate.hql.ast.antlr.sqlgenerator.getsqlstringwithlimitsifneeded(querywriter querywriter) @ nhibernate.hql.ast.antlr.sqlgenerator.endquery() @ nhibernate.hql.ast.antlr.sqlgenerator.selectstatement() @ nhibernate.hql.ast.antlr.sqlgenerator.statement() @ nhibernate.hql.ast.antlr.hqlsqlgenerator.generate() @ nhibernate.hql.ast.antlr.querytranslatorimpl.docompile(idictionary`2 replacements, boolean shallow, string collectionrole) @ nhibernate.hql.ast.antlr.querytranslatorimpl.compile(idictionary`2 replacements, boolean shallow) @ nhibernate.hql.ast.antlr.astquerytranslatorfactory.createquerytranslators(iastnode ast, string queryidentifier, string collectionrole, boolean shallow, idictionary`2 filters, isessionfactoryimplementor factory) @ nhibernate.hql.ast.antlr.astquerytranslatorfactory.createquerytranslators(iqueryexpression queryexpression, string collectionrole, boolean shallow, idictionary`2 filters, isessionfactoryimplementor factory) @ nhibernate.engine.query.queryexpressionplan.createtranslators(iqueryexpression queryexpression, string collectionrole, boolean shallow, idictionary`2 enabledfilters, isessionfactoryimplementor factory) @ nhibernate.engine.query.queryexpressionplan..ctor(iqueryexpression queryexpression, boolean shallow, idictionary`2 enabledfilters, isessionfactoryimplementor factory) @ nhibernate.engine.query.queryplancache.gethqlqueryplan(iqueryexpression queryexpression, boolean shallow, idictionary`2 enabledfilters) @ nhibernate.impl.abstractsessionimpl.gethqlqueryplan(iqueryexpression queryexpression, boolean shallow) @ nhibernate.impl.abstractsessionimpl.createquery(iqueryexpression queryexpression) @ nhibernate.linq.defaultqueryprovider.preparequery(expression expression, iquery& query, nhlinqexpression& nhquery) @ nhibernate.linq.defaultqueryprovider.execute(expression expression) @ nhibernate.linq.defaultqueryprovider.execute[tresult](expression expression) @ remotion.linq.queryablebase`1.getenumerator() @ system.collections.generic.list`1..ctor(ienumerable`1 collection) @ system.linq.enumerable.tolist[tsource](ienumerable`1 source) @ trim.chibro.services.base.operations.listodpoperation.execute(listodpdto filter) in c:\progetti.svn.cloud\chibro\chibromes\src\trim.chibro.services\base\operations\listodpoperation.cs:line 30 @ trim.chibro.services.implementations.listodpservice.execute(listodpdto filter) in c:\progetti.svn.cloud\chibro\chibromes\src\trim.chibro.services\implementations\listodpservice.cs:line 20 @ trim.chibro.web.controllers.listodpcontroller.index(listodpmodel model) in c:\progetti.svn.cloud\chibro\chibromes\src\trim.chibro.web\controllers\listodpcontroller.cs:line 75 @ lambda_method(closure , controllerbase , object[] ) @ system.web.mvc.actionmethoddispatcher.execute(controllerbase controller, object[] parameters) @ system.web.mvc.reflectedactiondescriptor.execute(controllercontext controllercontext, idictionary`2 parameters) @ system.web.mvc.controlleractioninvoker.invokeactionmethod(controllercontext controllercontext, actiondescriptor actiondescriptor, idictionary`2 parameters) @ system.web.mvc.async.asynccontrolleractioninvoker.actioninvocation.invokesynchronousactionmethod() @ system.web.mvc.async.asynccontrolleractioninvoker.<begininvokesynchronousactionmethod>b__39(iasyncresult asyncresult, actioninvocation innerinvokestate) @ system.web.mvc.async.asyncresultwrapper.wrappedasyncresult`2.callenddelegate(iasyncresult asyncresult) @ system.web.mvc.async.asyncresultwrapper.wrappedasyncresultbase`1.end() @ system.web.mvc.async.asyncresultwrapper.end[tresult](iasyncresult asyncresult, object tag) @ system.web.mvc.async.asynccontrolleractioninvoker.endinvokeactionmethod(iasyncresult asyncresult) @ system.web.mvc.async.asynccontrolleractioninvoker.asyncinvocationwithfilters.<invokeactionmethodfilterasynchronouslyrecursive>b__3d() @ system.web.mvc.async.asynccontrolleractioninvoker.asyncinvocationwithfilters.<>c__displayclass46.<invokeactionmethodfilterasynchronouslyrecursive>b__3f() @ system.web.mvc.async.asynccontrolleractioninvoker.<>c__displayclass33.<begininvokeactionmethodwithfilters>b__32(iasyncresult asyncresult) @ system.web.mvc.async.asyncresultwrapper.wrappedasyncresult`1.callenddelegate(iasyncresult asyncresult) @ system.web.mvc.async.asyncresultwrapper.wrappedasyncresultbase`1.end() @ system.web.mvc.async.asyncresultwrapper.end[tresult](iasyncresult asyncresult, object tag) @ system.web.mvc.async.asynccontrolleractioninvoker.endinvokeactionmethodwithfilters(iasyncresult asyncresult) @ system.web.mvc.async.asynccontrolleractioninvoker.<>c__displayclass21.<>c__displayclass2b.<begininvokeaction>b__1c() @ system.web.mvc.async.asynccontrolleractioninvoker.<>c__displayclass21.<begininvokeaction>b__1e(iasyncresult asyncresult)
in stack trace can see problem comes within getlimitstring() , helpers, answers question why happens skip() present. if there no skip/take there no reason apply limit/offset sql , therefore method never called.
as problem it's bit difficult. nhibernate has magic sql apply limit/offset mssql dialects before 2012 since lack straightforward sql syntax feature.
i can't tell if there problem escaping in code, or if hitting case nhibernate's mssqlselectparser wasn't designed.
if grab nhibernate source code , pdb-file, can try debugging down top 5 lines of stack trace , step trough see goes wrong.
Comments
Post a Comment