On Tue, 12 Apr 2011 13:17:51 +0100, "Richard Brown \(gmail\)"
<[email protected]> wrote:
>> ... 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.

I think Harald's point was about the generated SQL, not the intermediate
linq representation.

I'm definitely of the opinion that linq providers should translate .net
semantics into their underlying storage/object provider as faithful as
possible and shield the user from implementation details as much as
possible. I see no reason why the latter expression could not translate to
"(UserName is null and nullVar is null) or (UserName = nullVar)".

Best Regards, David

> 
> 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

Reply via email to