Problem in use if condition for nullable boolean in linq to NHibernate

Description

I have a `Person` class that `Sex` property is nullable.

public class Person { public bool? Sex {get; set;} }

And I have a query by linq to NHibernate.

var q = SessionInstance.Query<Person>(); if (dto.Sex != null) q = q.Where(p => p.Sex == dto.Sex); return q.ToList();

Now if value of dto.Sex equals `true`, result is correct.

But if value of dto.Sex equals `false` result is not correct because result is contain persons that Sex is false or null.

I checked profiler for this query:

select * from Person_Person person0_ where case when person0_.Sex = 1 then 1 else 0 end = case when 0 /* @p0 */ = 1 then 1 else 0 end

I don't know why that LINQ query generates a case statement, that's really weird.

Environment

None

Activity

Show:

Alex Zaytsev 
October 31, 2016 at 8:41 PM

Alex Zaytsev 
June 8, 2016 at 12:13 AM

In EF they do very-deep null propagation analysis on expression and extend it to conditional/more complex expression. This is not a matter of just adding random case statements to the query. I'll nominate this to 5.0

Oskar Berggren 
September 2, 2014 at 8:44 PM

Changing back to 4.1.0. Fixing this involves changing the result of a previously non-failing query, so it could mean a breaking change for some application, right?

Oskar Berggren 
December 13, 2012 at 10:43 PM

Let's see if we can get this done in NH4.0.

Oskar Berggren 
December 13, 2012 at 10:42 PM
(edited)

This might be relevant to explore in relation to this issue or something similar for other nullable primitives:

With Employee.ReportsTo as Nullable<int>, and this LINQ: var queryable = session.Query<Employee>() .Where(e => (e.ReportsTo != e.ReportsTo) == null);

L2EF generates:

WHERE CASE WHEN ( [Extent1].[flags] = [Extent1].[flags] ) THEN Cast(1 AS BIT) WHEN ( [Extent1].[flags] <> [Extent1].[flags] ) THEN Cast(0 AS BIT) END IS NULL

Nhibernate 3.3.x currently generates

where case when employee0_.ReportsTo<>employee0_.ReportsTo then 1 else 0 end=@p0; @p0 = NULL [Type: Boolean (0)]

And these two queries will of course give different results.

Fixed

Details

Assignee

Reporter

Labels

Components

Fix versions

Affects versions

Priority

Who's Looking?

Open Who's Looking?
Created March 26, 2012 at 10:37 AM
Updated December 18, 2017 at 9:26 PM
Resolved February 14, 2017 at 11:33 PM
Who's Looking?