A null reference exception is thrown when a Linq select query contains a cast to primitive type but the query returns null for the field. By example, when x.Id is typed as object but is mapped as int, and Class1.Field is int:
or when NestedField.Id is int, but x.NestedField is null:
This was working with NHibernate 3.x, but it throws with 4.x.
I have investigated this issue and found a solution for me in class NHibernate.Linq.Visitors.SelectClauseVisitor: I catch NullReferenceException when result is converted to property type:
As for NH-4059, the object typed property casted back to a primitive type does not look to me as a good pattern anyway. But the second example could look more legit.
Still, we have here a SQL semantic leaks inside .Net code. Null propagation is the SQL null handling mode, but that is not the way .Net handles them by default. Depending on how the lambda is processed, this SQL behavior was, according to your findings, leaking up to the projection processing with some NHibernate versions, resulting in affecting default(type) instead of throwing an exception as .Net behavior would have do. From a .Net standpoint, it would be more correct to rewrite your second case:
Your first case should be similarly handled.
Whether we should (re?)enable null propagation for Linq projections is debatable. I would need first to check what would have lead to this change for settling an opinion.
A null reference exception is thrown when a Linq select query contains a cast to primitive type but the query returns
null
for the field.By example, when
x.Id
is typed asobject
but is mapped as int, andClass1.Field
isint
:or when
NestedField.Id
isint
, butx.NestedField
isnull
:This was working with NHibernate 3.x, but it throws with 4.x.
I have investigated this issue and found a solution for me in class
NHibernate.Linq.Visitors.SelectClauseVisitor
:I catch
NullReferenceException
when result is converted to property type: