Skip to content

Custom Equality Fails #2791

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
PleasantD opened this issue May 26, 2021 · 1 comment
Closed

Custom Equality Fails #2791

PleasantD opened this issue May 26, 2021 · 1 comment

Comments

@PleasantD
Copy link
Contributor

PleasantD commented May 26, 2021

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 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.

@PleasantD
Copy link
Contributor Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants