How will C# 6.0's null-conditional operator affect your proposal? that is
in C# 6.0 you can write:
from Person p in session.Query<Person>()
select new {
Person = p.Name,
Pet = p.?Pet.Name
}
rather than
from Person p in session.Query<Person>()
select new {
Person = p.Name,
Pet = p.Pet != null ? p.Pet.Name : null
}
And the compiler will spit out an equivalent expression tree.
On Wednesday, May 6, 2015 at 1:46:48 PM UTC-4, [email protected] wrote:
>
> Well in my post, that's the code.
>
> I currently work around it by actually writing these null checks myself
> but at the database level they make no sense of course.
>
> Try the code with these data in the tables:
> *Person*
> *Id Name **PetId*
> 1 Test 1
>
> *Pet*
> *Id Name*
> 1 Test
>
> Notice how the query just executes fine. Now add a second record but with
> PetId NULL. Notice the crash.
>
> Note I was not proposing to do the transformation of the Expression Tree
> before it is handed to HQL but before it is compiled to a delete for use in
> the ResultTransformer.
>
>
> On Wednesday, May 6, 2015 at 12:11:45 PM UTC+2, Gunnar Liljas wrote:
>
>> I'm wondering in what kind of scenario you are experiencing this, because
>> that is most definitely not how NHibernate works. I use queries like the
>> mentioned all the time, without issues.
>>
>> Do you have some code you could show?
>>
>> Rewriting the expression to include null checks would create a more
>> complex Linq tree, a more complex HQL tree and eventually a more complex
>> SQL expression.
>>
>> /G
>>
>> 2015-05-05 17:47 GMT+02:00 <[email protected]>:
>>
>>> Consider the following domain model:
>>>
>>> public class Person {
>>> public virtual int Id { get; set;}
>>>
>>> public virtual string Name { get;set; }
>>>
>>> public virtual Pet Pet { get; set; }
>>> }
>>>
>>> public class Pet {
>>> public virtual int Id { get; set;}
>>>
>>> public virtual string Name { get;set; }
>>> }
>>>
>>>
>>> And the following LINQ query:
>>>
>>> from Person p in session.Query<Person>()
>>> select new {
>>> Person = p.Name,
>>> Pet = p.Pet.Name
>>> }
>>>
>>>
>>> This query executes fine, until there is a person which has no pet. The
>>> query then fails with a NullReferenceException somewhere deep in NHibernate
>>> (or - at least it appears to be). This is because NHibernate simply
>>> compiles the projection expression and executes it. To mitigate this one
>>> would need to write the query as follows:
>>>
>>> from Person p in session.Query<Person>()
>>> select new {
>>> Person = p.Name,
>>> Pet = p.Pet != null ? p.Pet.Name : null
>>> }
>>>
>>> The behavior is in my opinion confusing because other ORM (Entity
>>> Framework, amongst other) use database semantics here and this would simply
>>> cause the Expression "p.Pet.Name" to return NULL if any of the
>>> properties references in the expression return null. Even if one might want
>>> to adhere to the LINQ to Objects semantics instead, the
>>> NullReferenceException is best caught then rethrown with some useful
>>> message. The other problem is that writing these null checks polute the
>>> Expression tree passed to the LINQ provider.
>>>
>>> I propose to do make the following change:
>>>
>>> Before the Expression is compiled, a visitor will rewrite the Expression
>>> tree to add null checks. When a property is null default(T) will be
>>> returned. ExpressionToHqlTranslationResults seems the best place to do this.
>>>
>>> Are you willing to receive a contribution that will implement this, or
>>> is the current behavior deliberate?
>>>
>>> --
>>>
>>> ---
>>> 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 [email protected].
>>> 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 [email protected].
For more options, visit https://groups.google.com/d/optout.