You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
As of v5.3+ custom equality (and comparison) method handling is no longer possible for non-primitive types.
Let me unpack that.
We have a custom HQL generator implemented for object.Equals, since that isn't supported by NH directly.
The reason we need it is due to custom code that generates LINQ query expressions which need to be both C# and NH compatible, so in some cases we must use object.Equals(object) to correctly test for equality.
An example generated expression might look equivalent to e => (MyEnum.A).Equals((object)e.MyEnumProp)
Prior to v5.3.0 this worked fine for us.
After v5.3.0 this causes us errors, specifically when the mapped property is a String Enum type.
This method of the visitor is hit prior to evaluating the types of the parameters.
It appears to be building a dictionary of "related" expression subtrees so that the parameter evaluator can figure out that Enum.A (a constant, and therefore an SQL parameter) is related to e.MyEnumProp (a mapped property) and can use the NH mapping to convert the parameter to the correct IType.
Only this branch never runs because object.Equals(object) is not on the hard-coded list of methods.
As a consequence, no relationship is added between the calling object and the mapped property argument.
Lacking any relationships, the parameter type evaluation falls back to guessing and, in this case, guesses that the parameter should be EnumType instead of EnumStringType . This generates SQL that attempts to compare a string column with an int parameter, with errors or bad results depending on the DB.
The text was updated successfully, but these errors were encountered:
I'll note that we've worked around this issue for enums specifically by modifying our generator code to use Expression.Equality in more cases. However, this issue may still present itself for custom user types if the type can't be guessed without the related expressions. I don't have a specific test for that, so the enum example remains the best test case.
As of v5.3+ custom equality (and comparison) method handling is no longer possible for non-primitive types.
Let me unpack that.
We have a custom HQL generator implemented for
object.Equals
, since that isn't supported by NH directly.The reason we need it is due to custom code that generates LINQ query expressions which need to be both C# and NH compatible, so in some cases we must use
object.Equals(object)
to correctly test for equality.An example generated expression might look equivalent to
e => (MyEnum.A).Equals((object)e.MyEnumProp)
Prior to v5.3.0 this worked fine for us.
After v5.3.0 this causes us errors, specifically when the mapped property is a String Enum type.
Some investigation led me to the following code
https://github.com/nhibernate/nhibernate-core/blob/5.3.8/src/NHibernate/Linq/Visitors/ParameterTypeLocator.cs#L249
This method of the visitor is hit prior to evaluating the types of the parameters.
It appears to be building a dictionary of "related" expression subtrees so that the parameter evaluator can figure out that
Enum.A
(a constant, and therefore an SQL parameter) is related toe.MyEnumProp
(a mapped property) and can use the NH mapping to convert the parameter to the correctIType
.Only this branch never runs because
object.Equals(object)
is not on the hard-coded list of methods.As a consequence, no relationship is added between the calling object and the mapped property argument.
Lacking any relationships, the parameter type evaluation falls back to guessing and, in this case, guesses that the parameter should be
EnumType
instead ofEnumStringType
. This generates SQL that attempts to compare a string column with an int parameter, with errors or bad results depending on the DB.The text was updated successfully, but these errors were encountered: