NHibernate fails to add the correct params to a SQL parameterised query when performing a Linq query upon an entity type which is mapped one-to-one. This leads to a crash from the corresponding ADO driver when NHibernate attempts to execute the query. A full reproduction solution is attached but in short, here's the problem:
That query - where the "Person" and "Employee" classes are mapped with a one-to-one relationship - crashes with the following exception:
The reproduction case attached uses a SQLite database, but I have also been able to reproduce it using an MS-SQL database.
Note that I wrote the reproduction case project using Mono, and thus it depends upon Mono.Data.Sqlite at present. If you wish to execute the reproduction case on Windows/.NET, remove the reference to Mono.Data.Sqlite and download/install Sqlite from nuget.
To try the reproduction case (after making any changes for Sqlite), compile and execute the solution (there is only one project). The ReproductionCase class contains the logic which triggers this crash. The EntryPoint class just sets up and configures the session factory and db instance (including creating/exporting the schema).
Debian Wheezy GNU/Linux with Mono:
Mono JIT compiler version 3.12.1 (tarball Fri Mar 6 19:12:47 UTC 2015)
I have also seen this reproducible on a colleagues Windows machine running the official .NET framework 4.5
Oops, I forgot to mention that this issue also affects NH 3.3.3 (which is how we initially found it).
I am unsure if 3.x is still being supported with bugfixes but it would be nice if any fix were also backported as we are yet to make the upgrade to 4.0.
Person class doesn't have an equality operator implementation. In your case (in LinqToObject scenario) is better to compare objects via Objects.Equals method
But Person.Equals method implementation may be quite complex and may not be converted to sql query. So in NH case the following code is more preferred and it produces the correct sql query
As my mind this is not a bug and issue may be closed.
I understand that. However, in a many-to-one mapping scenario you can write equality operations just like that which are converted to SQL correctly without crashing. There is no need in that instance either to write an equality method implementation or operator overload. NH will correctly interpret it as a SQL equality comparison between the PK/FK values as applicable. NH only fails like this when the entities are mapped one-to-one.
If it is intentional that this does not work for one-to-one mappings and it cannot be implemented, surely a NotSupportedException would be preferable to producing and attempting to execute invalid SQL?