My thanks to you. Everyone here appreciates your relentless struggle to improve NH. Just had to get that one off my chest!
Love, Stefan :-) From: [email protected] [mailto:[email protected]] On Behalf Of Fabio Maulo Sent: Wednesday, July 28, 2010 2:42 PM To: [email protected] Subject: Re: [nhibernate-development] NH-2254 I'll follow your advise. Thanks. On Wed, Jul 28, 2010 at 7:39 AM, Wenig, Stefan <[email protected]<mailto:[email protected]>> wrote: With a single constant parameter, it's much easier to do escaping right. Does the new provider do that for parameters of StartsWith()? I'd expect something like this (TSQL): x.StartsWith (y + z) => ... WHERE x LIKE ESCAPE_WILDCARDS(y + z) + '%' ESCAPE '\' Where ESCAPE_WILDCARDS would be defined as: REPLACE (REPLACE (REPLACE (REPLACE (REPLACE(@str, '\', '\\'), '%', '\%'), '_', '\_'), '[', '\['), ']', '\]') If we can't do that, we better limit ourselves to the capabilities of the old provider and do constant escaping in memory. Better simple and correct than powerful and wrong, not? Non-constant patterns for LIKE are a rare sight anyway. What I wrote is just the SQL, but the new provider never generates SQL, just HQL. I have no idea whether this is even possible in HQL. (I read that ESCAPE is available in Java-Hibernate since v3, no idea how ESCAPE_WILDCARDS could be done in HQL. BTW, I still think we should have access to the interim HQL when discussing LINQ2NH.) Partial evaluation is a good point. Fortunately, re-linq already does partial evaluation on expressions before LINQ2NH even sees them. Unfortunately, the +'%' operation is not even there at that time. So you could consider replacing the StartsWith(x) with some Like(x.EscapeWildcards() + '%') expression in the QueryModel and then calling the partial evaluator of re-linq again. Should work, meet us on our users list if you want to try that. Last but not least, I'd like to say that I'd be happy if we could discuss LINQ issues without a constant debate whether something is really necessary or not. If Steve doesn't want to do it, fine. If nobody wants to send a patch either, the issue should be closed. But as long as there are people interested in fixing or implementing stuff, why close an issue? And Fabio, the constant lament about NH not needing more users, and LINQ just being the fifth wheel on a car with lots of query capabilities already, that's just frustrating and helps no one. We've all put a lot of work into the new LINQ provider, please don't treat it like that just because it's not your favorite feature. If nobody wants to fix it and people still complain, there's still enough time to get all defensive. Thanks, Stefan > -----Original Message----- > From: > [email protected]<mailto:[email protected]> > [mailto:nhibernate-<mailto:nhibernate-> > [email protected]<mailto:[email protected]>] On Behalf > Of Frans Bouma > Sent: Wednesday, July 28, 2010 9:16 AM > To: > [email protected]<mailto:[email protected]> > Subject: RE: [nhibernate-development] NH-2254 > > > That is not the solution because in OO what you have to write is: > > "something".Should().StartsWith("some"); > > Why? .StartsWith() is a bool returning method usable in a > predicate. > I have no idea why I should add '.Should()': > > var q = from c in session.Linq<Customer>() > where c.CompanyName.StartsWith("Foo") > select c; > > this is a simple, legitimate query which should result in a > simple > select on customer with a LIKE predicate having the pattern "Foo%". > > > but when you have to translate it for RDBMS you have to fit the > mismatch > > translating it to a like 'some%' > > that's not a mismatch, it exactly matches the rows you ordered it > to > match. > > > and ... > > var myPrefix = "so"; > > "something".Should().StartsWith(myPrefix + "m"); > > > > should be translated to > > like @prefix || 'm' || '%' > > why should that translate to that? > myPrefix is an in-memory constant and "m" is a constant. This is > 'funcletized' away (at least it _should_ by the linq provider) into a > lambda > which is compiled into a delegate (that's 1 call) and ran in-memory at > the > spot, resulting in "som". That's the constant then used in > StartsWith(). > > If you don't scan for in-memory constructs and compile them into > delegates, you can't handle things like: > > var q = from c in session.Linq<Customer>() > where c.CompanyName.StartsWith(GetCompanyStartFragment()) > select c; > > exactly the same thing. > > Now, why does the o/r mapper core NEED to have the '%' been split > from the actual pattern? > > FB > > > > > > > On Tue, Jul 27, 2010 at 6:32 PM, Frans Bouma > > <[email protected]<mailto:[email protected]>> wrote: > > > > > > > I have closed the issue. > > > > > > For me it is an external issue; we can't endorse all > workarounds... > > if an > > > RDBMS has an issue is not our problem and for some reason we > give > > six ways > > > to query the persistence (4 are completely OO). > > > > > > I would like heard your opinions. > > > > > > I fail to see why the linq provider creates the second > query > > (@p0+'%'). > > > > The reason is that the StartsWith / EndsWith/Contains > calls > on > > 'string' are easy to deal with and you can just formulate a like > > query with > > a pattern, no need for parameter concatenation (i.e.: the > parameter > > value IS > > the pattern). > > > > I.o.w. a useless restriction (and IMHO a legitimate > > bugreport). > > > > FB > > > > > > > > > > > > > > -- > > Fabio Maulo > > > -- Fabio Maulo
