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 nhibernate-development+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to