... one behavior of Linq2SQL which I cannot qualify other than "very weird" ...

FWIW, that's pretty much what I would expect a LINQ provider to do.


I would expect:
   session.CreateQuery("from User u where u.UserName is null")

to translate to (using a literal):
   .Where(u => u.UserName == null)


... and I would expect:
session.CreateQuery("from User u where u.UserName = :name").SetString("name", nullVar)

... to translate to:
   .Where(u => u.UserName == nullVar)


But maybe that's just me.

Richard

-----Original Message----- From: Harald Mueller
Sent: Tuesday, April 12, 2011 12:27 PM
To: [email protected]
Subject: Re: RE: [nhibernate-development] NH-2583 - Query with || operator and navigations (many-to-one) creates wrong joins

Hi - not at all a "dumb question".

Has there ever been a general discussion about how close NH's LINQ
provider actually _wants_ to be to LINQ to objects?

I do not know whether such a discussion + results has been done.
My contribution are (few) conceptual texts about expected semantics / behavior with examples - see the one I attached to the jira entry, where I argued that one should in principle stick to Linq2Objects semantics. However, Patrick is convinced that we should another semantics ("pure outer join semantics" or (||-4)-semantics in my text), for which I have not yet written an explaining text ... but I certainly will.

In any case, 100% compatibility to LINQ 2 objects is an illusion. You'll
never get there, so you might as well not try.

May I suggest that you read my text at the jira entry where I argue for various, *defined" deviations from LINQ2Objects? The main idea I had is that for all cases where LINQ2Objects does *not* throw an exception, the behaviors are identical; and this *is* feasible at least for navigation and the &&, |, !, and Any operators. It depends on what you mean by "illusion" - but as both SQL and Linq(2Objects) semantics are precisely defined and strong enough, it is certainly possible to have 100% compatibility at least under my (BEHAV-3) rule. Still, especially performance arguments might make us agree that a differing semantics is better for all practical purposes - which is why Patrick suggested a different, deviating (also from Linq2Objects' non-exceptional behavior) semantics, which I now try to implement for the logical operators (I'm almost there ...).

Consider the typical
NullReference problem:

a.b.c == x

What's this code supposed to do if a.b is null? In C#, you'd get a
NullReferenceException. Do you want the same in SQL? Why?

See (BEHAV-1) ... (BEHAV-4). Other possibilities are Patrick's "Copy EF semantics" or your suggestion "Copy Linq2SQL semantics" ...

My suggestion is to copy the behavior of LINQ to SQL and stay as close to
SQL as you can, because that's easier to handle for the user, and less
likely to bring surprises.

... but both these suggestions obviously have the problem that there is no useful definition of these semantics and, especially, their design targets (e.g., do they want to follow de'Morgan's laws everywhere - so if they don't, it's a bug?).

Moreover, I would strongly argue that NHibernate should NOT duplicate one behavior of Linq2SQL which I cannot qualify other than "very weird", namely the null-constant vs. null-in-a-variable anomaly: (In some version - I did not look recently) Linq2SQL creates SQL
  P IS NULL
from Linq
  ...Where(x => x.P == null)...
but it creates
  P = NULL --- which is never true
from
  SomeType nullVar = null;
  ...Where(x => x.P == nullVar)...

And because I do not believe that the Linq2SQL semantics is consistent (i.e., not contradictory), we should also look at certain conditions, e.g. those with !Any ("not any") - these are classical examples where OR mappings fail (because some people assume erroneously that "Any" can always by evaluated with joins and no sub-selects ...).

Also, AFAIK, Linq2SQL can only handle the "table per hierarchy" strategy for inheritance - and we would certainly not want to duplicate *this* limitation in NHibernate.Linq, wouldn't we?

So, it seems to me that some people ("you"? "we"?) still need to define (parts of) NHibernate.Linq's semantics better so that it is clear

* what constitues a bug (a deviation from that defined semantics); and
* what is a feature (a designed deviation from Linq2Objects semantics).

And in the course of this discussion one would also establish design targets (at least all the meta-rules from logics - like de'Morgan, neutrality of contradictions for || and tautologies for &&, associativity etc.), as these are fundamentally used by all programmers to argue about correctness of and find bugs in their application code. Therefore, I completely agree with you on the following:

In any case, there needs to be a clear and concise documentation for
translation results. It's just a language that you need to learn before you use
it. If one has to look up everything in unit tests or try it out, or even
memorize many inconsistent cases, LINQ becomes a burden. A wiki page will
do. A reference to unit tests won't.

And I'm quite sure that such a definition needs

(a) (many...) examples

(b) but also a discussion of the "meta-rules" mentioned above - e.g., do we want de'Morgan to hold (as it does in propositional logic, C#, and SQL) or not? do we require that "false" (or any contradiction) is a neutral element for || - i.e., that we always have P || false exactly if P? etc.etc.

[The problem with such rules is that they may have consequences that are not immediately visible: contradict each other; or contradict the wanted behavior of some examples ... but this is well known to all that work in logics. If you are interested: try to invent all possible consistent 4-valued logics; and for a "very meta" problem of that sort, read about "material implication" and "strict conditional"].

Anyway, yes, you are right, such a discussion - certainly including proofs/arguments of wanted / not wanted properties of the ensuing logic - plus documentation is a good thing!

Just my two cents.
Your text was, IMHO, more than that :-)

Regards
Harald


--
GMX DSL Doppel-Flat ab 19,99 Euro/mtl.! Jetzt mit
gratis Handy-Flat! http://portal.gmx.net/de/go/dsl

Reply via email to